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