QPainter、QPaintEngine、QPaintDevice組成了Qt的 繪圖系統(The Paint System),QPainter
提供低階的繪圖API,在內部使用QPaintEngine作為介面,在QPaintDevice進行繪圖,只要是QPaintDevice的子類別,就
可以建立QPainter在其上進行圖形繪製,像是QWidget、QImage、QPicture、QPrinter等都是QPaintDevice的
子類別。
建立QPainter的方式如下,其中qPainterDevice是個指向QPaintDevice子類別的名稱:
QPainter painter(qPainterDevice);
若是圖形元件,通常會重新定義QWidget的paintEvent(),當繪圖裝置(Paint
Device)需要重繪時,就會發出QPaintEvent並分派給這個方法來處理事件,例如元件出現、被覆蓋又重現時,您也可以呼叫repaint()
或update(),這也會執行paintEvent()。
QPainter提供各種繪製圖形的API,從基本的線繪製、方塊、矩形、圓形、漸層到複雜的圖片等,QPainter都有提供相對應的API,使用的方式,在 QPainter 的說明文件 中,基本上都有提供,在這邊基本上要先了解的是,QPainter的三個基本設定:筆觸(Pen)、筆刷(Brush)與字型(Font)。
筆觸在Qt中是以QPen作代表,用來於繪製線條或輪廓時決定樣式,像是顏色、筆寬、轉折、線條樣式(實線、曲線、點狀線之類的樣式)等。
筆刷在Qt中是以QBrush作代表,用來於繪製矩形、圓形、扇形等幾何圖形時決定樣式,像是顏色、填滿樣式、漸層等。
以下先看一個簡單的程式,了解一下QPainter的幾個API,以及QPen、QBrush的使用:
#include <QApplication> #include <QWidget> #include <QPainter>
class PainterWidget : public QWidget { protected: // 重新定義paintEvent()事件處理 void paintEvent(QPaintEvent*); };
// 實作事件處理 void PainterWidget::paintEvent(QPaintEvent *event) { // 建立QPainter QPainter painter(this);
// 設定筆觸為點狀線 painter.setPen(Qt::DotLine);
// 指定x、y、width、height繪製線條 painter.drawLine(10, 10, 100, 10); // 設定筆刷為藍色、對角斜線樣式 painter.setBrush(QBrush(Qt::blue, Qt::BDiagPattern));
// 指定x、y、width、height繪製矩形 painter.drawRect(10, 20, 100, 50); // 設定線形漸層,x1,y1為起點,x2,y2為終點 QLinearGradient gradient(50, 100, 300, 350);
// 設定漸層顏色過渡 gradient.setColorAt(0.0, Qt::white); gradient.setColorAt(0.2, Qt::green); gradient.setColorAt(1.0, Qt::black);
// 以漸層物件建立筆刷 painter.setBrush(QBrush(gradient));
// 繪製圓角矩形 painter.drawRoundRect(10, 80, 100, 50);
// 繪製扇形,單位為 1/16 角度,下例為 45 度 到 300 度 painter.drawPie(10, 150, 100, 50, 45 * 16, 300 * 16);
// 繪製圖片 painter.drawPixmap(150, 10, QPixmap("caterpillar.jpg"));
// 繪製填滿圖形 painter.drawTiledPixmap(150, 170, 185, 25, QPixmap("caterpillar_smaill.gif")); }
int main(int argc, char *argv[]) { QApplication app(argc, argv); PainterWidget pWidget; pWidget.setWindowTitle("QPainter"); pWidget.resize(350, 200); pWidget.show(); return app.exec(); }
執行的結果如下所示:

QPainter
類別中的drawText()方法可以在繪圖裝置上繪製文字,也可以設定繪製時所用的字型,字型在Qt中是使用QFont代表,在設定好字型之後,可以用fontMetrics()方法
取得字型的幾何資訊,例如ascent(字元最高點至字元底線baseline距離)、descent(字元最低點到字元底線距離)、leading(兩
行之間的空間值)height(字體印字時的高度,相當於 ascent+descent
+1,1pixel是字元底線的高度)與linespacing(height+leading)等。

下面這個程式是文字繪製的簡單示範,利用迴圈展示三種字型、五種大小不同組合下的文字繪製效果:
#include <QApplication> #include <QWidget> #include <QPainter>
class PainterWidget : public QWidget { protected: void paintEvent(QPaintEvent*); };
void PainterWidget::paintEvent(QPaintEvent *event) { QPainter painter(this); static const char *fonts[] = {"Helvetica", "Courier", "Times", 0}; static int sizes[] = {10, 12, 18, 24, 36, 0}; int f = 0; int y = 0; while (fonts[f]) { int s = 0; while (sizes[s]) { QFont font(fonts[f], sizes[s]); painter.setFont(font); QFontMetrics fm = painter.fontMetrics();
y += fm.ascent(); painter.drawText(10, y, "Hello! caterpillar!"); y += fm.descent(); s++; } f++; } }
int main(int argc, char *argv[]) { QApplication app(argc, argv); PainterWidget pWidget; pWidget.setWindowTitle("QPainter"); pWidget.resize(600, 450); pWidget.show(); return app.exec(); }
下圖為執行時的結果畫面:

|
|