Qt-繪圖
1 簡介
參考視頻://www.bilibili.com/video/BV1XW411x7NU?p=37
參考文檔:《Qt教程.docx》
本文簡單介紹Qt的繪圖與繪圖設備。
Qt的繪圖系統基於三個類:QPainter,QPainterDevice和QPaintEngine。它們之間的層次關係結構如下:
QPainter:用於執行繪圖的操作,可以把它想像成畫家;
QPaintDevice:一個二維空間的抽象,這個二維空間允許QPainter在其上進行繪製。想像成畫板;
QPaintEngine:提供了畫筆(QPainter)在不同的設備上進行繪製的統一的接口。對開發人員透明。
我們可以把QPainter理解成畫筆;把QPaintDevice理解成使用畫筆的地方,比如紙張、屏幕等;而對於紙張、屏幕而言,肯定要使用不同的畫筆繪製,為了統一使用一種畫筆,我們設計了QPaintEngine類,這個類讓不同的紙張、屏幕都能使用一種畫筆。
Qt 的繪圖系統實際上是,使用QPainter在QPainterDevice上進行繪製,它們之間使用QPaintEngine進行通訊(也就是翻譯QPainter的指令)。
2 測試
下面寫個測試代碼來進行說明。
功能:在窗口上繪製直線、矩形、橢圓、添加背景圖等。
(1)創建一個帶ui的QWidget工程
(2)實現過程
我們只需要重寫繪圖事件處理函數就可以了,也就是void paintEvent(QPaintEvent *event);
如果在窗口繪圖,必須放在繪圖事件里實現 ;窗口需要重繪的時候(狀態改變)繪圖事件內部自動調用。
(3)實現效果
最終實現的效果如下:
(4)步驟說明
1)首先,我們需要創建一個繪圖對象,並指定繪圖設備(也就是準備畫家和畫板)。有兩種方式:
方式一:QPainter p(this); //創建畫家,並指定當前窗口為繪圖設備。
方式二:
1 QPainter p; //創建畫家對象 2 p.begin(this); //指定當前窗口為繪圖設備 3 //繪圖操作 4 //p.drawxxxx(); 5 p.end();
我們這裡使用方式二。
2)上圖中的線寬以及顏色,我們是使用畫筆QPen實現的;上圖中矩形和橢圓形中的填充色,我們是使用畫刷QBrush實現的。
我們創建了畫筆對象和畫刷對象之後,需要把它們交給畫家,也就是QPainter。
1 //定義畫筆 2 QPen pen; 3 pen.setWidth(2); //設置線寬5pix 4 //pen.setColor(Qt::red); //設置顏色 5 pen.setColor(QColor(14, 9, 234)); //rgb設置顏色 6 pen.setStyle(Qt::DashLine); //設置風格 7 //把畫筆交給畫家 8 p.setPen(pen); 9 10 //創建畫刷對象 11 QBrush brush; 12 brush.setColor(Qt::red); //設置顏色 13 brush.setStyle(Qt::Dense1Pattern); //設置樣式 14 //把畫刷交給畫家 15 p.setBrush(brush);
3)繪製背景圖
使用drawPixmap函數,有好幾種方式,這裡說兩種:
1 // p.drawPixmap(0, 0, width(), height(), QPixmap(":/new/prefix1/image/superman.jpg")); 2 p.drawPixmap(rect(), QPixmap(":/new/prefix1/image/background.png")); //獲取矩形
4)繪製直線
上圖中的第一個正方形是用直線拼出來的,繪製直線使用drawLine()函數。
1 //畫直線 2 p.drawLine(20, 20, 100, 20); 3 p.drawLine(20, 20, 20, 100); 4 p.drawLine(20, 100, 100, 100); 5 p.drawLine(100, 20, 100, 100);
5)繪製矩形
1 //畫矩形 2 p.drawRect(120, 20, 100, 50);
6)繪製橢圓
1 //畫圓 2 p.drawEllipse(QPoint(170, 150), 50, 25);
5)繪製笑臉
上圖中顯示點擊按鈕並讓笑臉移動是使用update()函數實現的,當我們點擊按鈕時,就在按鈕的槽函數中調用update()進行更新窗口。
1 //畫笑臉 2 p.drawPixmap(x, 180, 80, 80, QPixmap(":/new/prefix1/image/face.png"));
下面給出widget.cpp的完整代碼:


1 #include "widget.h" 2 #include "ui_widget.h" 3 #include <QPainter> 4 #include <QPen> 5 #include <QBrush> 6 7 Widget::Widget(QWidget *parent) : 8 QWidget(parent), 9 ui(new Ui::Widget) 10 { 11 ui->setupUi(this); 12 13 x = 0; 14 } 15 16 Widget::~Widget() 17 { 18 delete ui; 19 } 20 21 void Widget::paintEvent(QPaintEvent *event) 22 { 23 //方式一: 24 // QPainter p(this); 25 26 //方式二: 27 QPainter p; //創建畫家對象 28 p.begin(this); //指定當前窗口為繪圖設備 29 //繪圖操作 30 //p.drawxxxx(); 31 //畫背景圖 32 // p.drawPixmap(0, 0, width(), height(), QPixmap(":/new/prefix1/image/superman.jpg")); 33 p.drawPixmap(rect(), QPixmap(":/new/prefix1/image/background.png")); //獲取矩形 34 35 //定義畫筆 36 QPen pen; 37 pen.setWidth(2); //設置線寬5pix 38 //pen.setColor(Qt::red); //設置顏色 39 pen.setColor(QColor(14, 9, 234)); //rgb設置顏色 40 pen.setStyle(Qt::DashLine); //設置風格 41 //把畫筆交給畫家 42 p.setPen(pen); 43 44 //創建畫刷對象 45 QBrush brush; 46 brush.setColor(Qt::red); //設置顏色 47 brush.setStyle(Qt::Dense1Pattern); //設置樣式 48 //把畫刷交給畫家 49 p.setBrush(brush); 50 51 //畫直線 52 p.drawLine(20, 20, 100, 20); 53 p.drawLine(20, 20, 20, 100); 54 p.drawLine(20, 100, 100, 100); 55 p.drawLine(100, 20, 100, 100); 56 57 //畫矩形 58 p.drawRect(120, 20, 100, 50); 59 60 //畫圓 61 p.drawEllipse(QPoint(170, 150), 50, 25); 62 63 //畫笑臉 64 p.drawPixmap(x, 180, 80, 80, QPixmap(":/new/prefix1/image/face.png")); 65 66 p.end(); 67 } 68 69 void Widget::on_pushButton_clicked() 70 { 71 x += 20; 72 if (x > width()) { 73 x = 0; 74 } 75 //刷新窗口,讓窗口重繪製,整個窗口都重繪 76 update(); //間接調用paintEvent 77 }
View Code
widget.h的代碼:


1 #ifndef WIDGET_H 2 #define WIDGET_H 3 4 #include <QWidget> 5 6 namespace Ui { 7 class Widget; 8 } 9 10 class Widget : public QWidget 11 { 12 Q_OBJECT 13 14 public: 15 explicit Widget(QWidget *parent = 0); 16 ~Widget(); 17 18 protected: 19 //重寫繪圖事件 20 //如果在窗口繪圖,必須放在繪圖事件里實現 21 //繪圖事件內部自動調用,窗口需要重繪的時候(狀態改變) 22 void paintEvent(QPaintEvent *event); 23 24 private slots: 25 void on_pushButton_clicked(); 26 27 private: 28 Ui::Widget *ui; 29 int x; 30 31 }; 32 33 #endif // WIDGET_H
View Code