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