1 简介
参考视频:https://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 }
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
来源:oschina
链接:https://my.oschina.net/u/4334817/blog/4336928