[Qt2D繪圖]-04繪制文字&&繪制路徑


注:學習自《Qt Creator 快速入門》第三版。
 
文檔中的示例參考
Qt Example推薦:Painter Paths Example和Vector Deformation
 
大綱:
    繪制文字
    繪制路徑
        path的填充規則
        QPainter中與path有關的常用函數
 
本篇涉及的Qt類: QPainter QFont QPainterPath
 
繪制文字 (QPainter::darwText())
除了繪制圖形以外,還可以使用QPainter::darwText()函數來繪制文字,
還可以使用QPainter::setFont()設置文字所使用的字體,使用QPainter::fontInfo()函數可以獲取字體的信息,它返回QFontInfo類對象。
繪制文字時會默認使用抗鋸齒。
 
drawText()函數有很多重載。這里演示一個:
void QPainter::drawText(const QRectF &rectangle, int flags, const QString &text, QRectF *boundingRect = nullptr)
  • 第一個參數指定了繪制文字所在的矩形;
  • 第二個參數指定了文字在矩形中的對齊方式,它由Qt::AlignmentFlag枚舉類型進行定義,不同對齊方式也可以使用按位或“|”操作符同時使用,這里還可以使用Qt::TextFlag定義的其他一些標志,比如自動換行等;
  • 第三個參數就是所要繪制的文字,這里可以使用“\n”來實現換行;
  • 第四個參數一般不用設置。
如果繪制的文字和它的布局不用經常改動,那么也可以使用drawStaticText。
 painter.drawStaticText(QPoint(120, 120),
                         QStaticText(QString("hello use drawStaticText")));
 
繪制路徑 (QPainter::drawPath(path))
如果要繪制一個復雜的圖形,尤其是要重復繪制復雜的圖形,可以使用 QPainterPath類,並使用QPainter: :drawPath()進行繪制。
QPainterPath類為繪制操作提供了一個容器,可以用來創建圖形並且重復使用。
一個繪圖路徑就是由多個矩形、橢圓、線條或者曲線等組成的對象,一個路徑可以是封閉的,如矩形和橢圓;也可以是非封閉的,如線條和曲線。
 
void Widget::paintEvent(QPaintEvent *event) {
QPainter painter(this);
  painter.setRenderHint(QPainter::Antialiasing);


  QPainterPath path;
  // 創建一個QPainterPath對象后就會以坐標原點為當前點進行繪制,
  // 可以使用moveTo()函數改變當前點,移動當前點到點(50,250)
  path.moveTo(50, 250);
  // 從當前點即(50,250)繪制一條直線到點(50,230).完成后當前點更改為(50,230)
  path.lineTo(50, 230);
  //從當前點和點(120,60)之間繪制一條三次貝塞爾曲線
  path.cubicTo(QPointF(105, 40), QPointF(115, 80), QPointF(120, 60));

  path.lineTo(130, 130);
  //向路徑中添加一個橢圓
  path.addEllipse(QPointF(130.0, 130.0), 30, 30);
  // 繪制path
  painter.drawPath(path);

  //平移坐標系統后再次繪制路徑
  path.translate(200, 0);
  painter.setPen(Qt::darkBlue);
  painter.drawPath(path);
}
 
關於path路徑"制作",主要是QpainterPath類的使用.
 
常用的方法:
可以使用lineTo()、arcTo()、cubicTo( )和quadTo()等函數將直線或者曲線添加到路徑中;
cubicTo (const QPointF &cl, const QPointF &c2, const QPointF &endPoint)函數可以在當前點和endPoint點之間添加一個3次貝塞爾曲線;
quadTo()函數可以繪制一個二次貝塞爾曲線;
可以使用addEllipse()、addPath()、addRect()、addRegion()、addText()和addPolygon()來向路徑中添加一些圖形或者文字。
它們都從當前點開始進行繪制,繪制完成后以結束點作為新的當前點。這些圖形都是由一組直線或者曲線組成.
currentPosition()函數獲取當前點;
使用moveTo()函數改變當前點;
當組建好路徑后可以使用drawPath()函數來繪制路徑;
可以使用translate()函數將路徑平移。
這也是QPainterPath的主要作用。
 
注:關於貝塞爾曲線來看一個書上的圖:
 
path的填充規則 (Qt::FillRule)
path的填充有兩個填充規則:
Qt::OddEvenFill(默認)和Qt::WindingFill。
QPainter painter(this);
  QPainterPath path;
// 此path沒有設置fillrule。則使用默認的Qt::OddEvenFill
  path.addEllipse(10,50,100,100);
  path.addRect(50,100,100,100);
painter.setBrush(Qt::cyan);
  painter.drawPath(path);
  

//此path手動設置填充規則
  painter.translate(180,0);
  path.setFillRule(Qt::WindingFill);
  painter.drawPath(path);
運行結果:
 
FillRule的理論部分:
Qt::OddEvenFill使用的是奇偶填充規則.
具體來說就是:如果要判斷一個點是否在圖形中,那么可以從該點向圖形外引一條水平線,如果該水平線與圖形的交點的個數為奇
數,那么該點就在圖形中。這個規則是默認值;
Qt::WindingFill使用的是非零彎曲規則.
具體來說就是:如果要判斷一個點是否在圖形中,那么可以從該點向圖形外引一條水平線,
如果該水平線與圖形的邊線相交,這個邊線是順時針繪制的,就記為1;是逆時針繪制的就記為一1。然后將所有數值相加,如果結果不為0,那么該點就在圖形中。
 
圖10- 19是這兩種規則的示意圖,對於Qt::OddEvenFill規則,第一個交點記為1,第二個交點記為2;
對於Qt::WindingFill規則,因為橢圓和矩形都是以順時針進行繪制的,所以各個交點對應的邊都使用1來代表。
 
關於QPainter 的與path有關的常用函數:
QPainter::fillPath()來填一個路徑;
QPainter::strokePath()函數來繪制路徑的輪廓;
QPainterPath::elementAt()來獲取路徑中的一個元素;
QPainterPath::elementCount()獲取路徑中元素的個數;
QPainterPath::contains()函數來判斷一個點是否在路徑中;
QPainterPath::toFillPolygon()函數將路徑轉換為一個多邊形。
...

 

本篇筆記的源代碼
代碼會整理到GitHub,如果沒有請等待https://github.com/tudouloveloli/QtExampleCode


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM