Qt之图形(QPainter的基本绘图)
2017-04-28 16:35
399 查看
简述
Qt中提供了强大的2D绘图系统,可以使用相同的API在屏幕和绘图设备上进行绘制,它主要基于QPainter、QPaintDevice和QPaintEngine这三个类。QPainter用来执行绘图操作,其提供的API在GUI或QImage、QOpenGLPaintDevice、QWidget和QPaintDevice显示图形(线、形状、渐变等)、文本和图像。
QPaintDevice不直接绘制物理显示画面,而利用逻辑界面的中间媒介。例如,绘制矩形图形时,为了将对象绘制到QWidget、QGLPixelBuffer、QImage、QPixmap、QPicture等多种界面中间,必须使用QPaintDevice。
QPaintEngine提供了一些接口,可以用于QPainter在不同的设备上进行绘制。
绘图系统由QPainter完成具体的绘制操作,QPainter类提供了大量高度优化的函数来完成GUI编程所需要的大部分绘制工作。它可以绘制一切想要的图形,从最简单的一条直线到其他任何复杂的图形,例如:点、线、矩形、弧形、饼状图、多边形、贝塞尔弧线等。此外,QPainter也支持一些高级特性,例如反走样(针对文字和图形边缘)、像素混合、渐变填充和矢量路径等,QPainter也支持线性变换,例如平移、旋转、缩放。
QPainter可以在继承自QPaintDevice类的任何对象上进行绘制操作。QPainter也可以与QPrinter一起使用来打印文件和创建PDF文档。这意味着通常可以用相同的代码在屏幕上显示数据,也可以生成打印形式的报告。
QPainter一般在部件的绘图事件paintEvent()中进行绘制,首先创建QPainter对象,然后进行图形的绘制,最后记得销毁QPainter对象。当窗口程序需要升级或者重新绘制时,调用此成员函数。使用repaint()和update()后,调用函数paintEvent()。
下面通过简单的示例来介绍成员函数paintEvent()的使用方法。
绘制文本
效果
源码
void MainWindow::paintEvent(QPaintEvent *event) { Q_UNUSED(event); QPainter painter(this); // 设置画笔颜色 painter.setPen(QColor(0, 160, 230)); // 设置字体:微软雅黑、点大小50、斜体 QFont font; font.setFamily("Microsoft YaHei"); font.setPointSize(50); font.setItalic(true); painter.setFont(font); // 绘制文本 painter.drawText(rect(), Qt::AlignCenter, "Qt"); }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
首先为该部件创建了一个QPainter对象,用于后面的绘制。使用setPen()来设置画笔的颜色(淡蓝色)。通过使用QFont来构建我们想要的字体,setFamily()设置字体为微软雅黑、setPointSize()设置点大小30、setItalic()设置斜体, 然后通过setFont()来设置字体,最后调用drawText()来实现文本的绘制,这里的rect()是指当前窗体的显示区域,Qt::AlignCenter指文本居中绘制。
绘制直线
效果
源码
void MainWindow::paintEvent(QPaintEvent *event) { Q_UNUSED(event); QPainter painter(this); // 反走样 painter.setRenderHint(QPainter::Antialiasing, true); // 设置画笔颜色 painter.setPen(QColor(0, 160, 230)); // 绘制直线 painter.drawLine(QPointF(0, height()), QPointF(width() / 2, height() / 2)); }1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
首先我们通过setRenderHint()来设置反走样,要么绘制出来的线条会出现锯齿,调用setPen()来设置画笔颜色(淡蓝色)。最后调用drawLine()来实现直线的绘制,其中QPointF(0, height())是指直线的起点坐标、QPointF(width() / 2, height() / 2)是指直线的终点坐标。
绘制矩形
效果
源码
void MainWindow::paintEvent(QPaintEvent *event) { Q_UNUSED(event); QPainter painter(this); // 反走样 painter.setRenderHint(QPainter::Antialiasing, true); // 设置画笔颜色、宽度 painter.setPen(QPen(QColor(0, 160, 230), 2)); // 设置画刷颜色 painter.setBrush(QColor(255, 160, 90)); painter.drawRect(50, 50, 160, 100); }1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14
首先我们使用setPen()来设置画笔颜色(淡蓝色)、宽度(2像素),用来设置矩形区域的边框。然后使用setBrush()来设置画刷颜色(橙色),用来填充矩形区域,最后调用drawRect()来实现矩形的绘制,其中参数依次顺序为x、y、w、h,是指区域从x为50,y为50的坐标点起,宽度为160,高度为100的矩形。
绘制弧线
效果
源码
void MainWindow::paintEvent(QPaintEvent *event) { Q_UNUSED(event); // 矩形 QRectF rect(90.0, 90.0, 80.0, 90.0); // 起始角度 int startAngle = 30 * 16; // 跨越度数 int spanAngle = 120 * 16; QPainter painter(this); // 反走样 painter.setRenderHint(QPainter::Antialiasing, true); // 设置画笔颜色、宽度 painter.setPen(QPen(QColor(0, 160, 230), 2)); // 绘制弧线 painter.drawArc(rect, startAngle, spanAngle); }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
画弧线时,角度被分成了十六分之一,就是说,如果要30度,就需是30*16。它有起始角度和跨度,还有位置矩形,所以,要想画出自己想要的弧线,就需要大概估算出各个参数的预估值。
绘制椭圆
效果
源码
void MainWindow::paintEvent(QPaintEvent *event) { Q_UNUSED(event); QPainter painter(this); // 反走样 painter.setRenderHint(QPainter::Antialiasing, true); // 设置画笔颜色、宽度 painter.setPen(QPen(QColor(0, 160, 230), 2)); // 绘制椭圆 painter.drawEllipse(QPointF(120, 60), 50, 20); // 设置画刷颜色 painter.setBrush(QColor(255, 160, 90)); // 绘制圆 painter.drawEllipse(QPointF(120, 140), 40, 40); }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
这里我们绘制了一个椭圆和一个圆形,都是调用drawEllipse接口,我们可以很轻易的发现,如果为椭圆的时候,后面两个参数不一样,圆形则相同。首先我们来看第一个参数QPointF是指椭圆的中心点相对当前窗体QPoint(0, 0)点的位置,后面的参数指椭圆的x轴及y轴的半径。
绘制多边形
效果
源码
void MainWindow::paintEvent(QPaintEvent *event) { Q_UNUSED(event); QPainter painter(this); // 反走样 painter.setRenderHint(QPainter::Antialiasing, true); // 设置画笔颜色 painter.setPen(QColor(0, 160, 230)); // 各个点的坐标 static const QPointF points[4] = {QPointF(30, 40), QPointF(60, 150), QPointF(150, 160), QPointF(220, 100)}; // 绘制多边形 painter.drawPolygon(points, 4); }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
首先我们顶一个个坐标点的位置,这里有四个点,分别为:QPointF(30, 40)、QPointF(60, 150)、QPointF(150, 160)、 QPointF(220, 100),然后调用drawPolygon将各个点连接起来,绘制为多边形。
绘制图片
效果
源码
void MainWindow::paintEvent(QPaintEvent *event) { Q_UNUSED(event); QPainter painter(this); // 反走样 painter.setRenderHint(QPainter::Antialiasing, true); // 绘制图标 painter.drawPixmap(rect(), QPixmap(":/Images/logo")); }1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
通过drawPixmap()来绘制图片,我们可以指定图片绘制的区域QRect,这里为整个界面的区域,当界面伸缩的时候,图片也会跟着伸缩。
总结
QPainter接收一个QPaintDevice*类型的参数。QPaintDevice有很多子类,比如QImage,以及QWidget。注意回忆一下,QPaintDevice可以理解成要在哪里去画,而现在我们希望在这个widget上画,因此传入的是this指针。QPainter有很多以draw开头的函数,用于各种图形的绘制,比如这里的drawLine,drawRect和和drawEllipse等。具体的参数请参阅API文档。下图给出了QPainter的draw函数的实例,本图来自C++ GUI Programming with Qt4, 2nd Edition.
基本的文本、直线、矩形、椭圆、多边形、图片的绘制已经分享完了,还有一些细节我们没有讲解,关于其它图形的绘制也大同小异,这些我们都在后面做详细的讲解。
相关文章推荐
- Qt之图形(QPainter的基本绘图)
- Qt之图形(QPainter的基本绘图)
- Qt之图形(QPainter的基本绘图)
- 我的Qt学习之路——QPainter基本绘图
- QT中QPainter的使用及矩形、圆形等常见图形的画法
- Visual C++游戏开发笔记之四——游戏画面绘图(一)基本图形绘制
- 【Visual C++】游戏开发笔记之四――游戏画面绘图(一)基本图形绘制
- 【Visual C++】游戏开发笔记之四——游戏画面绘图(一)基本图形绘制
- Cairo 图形指南 (4) —— 基本绘图
- 如何使用QT的QPainter绘图和实时刷新?
- 利用QT中Qpainter画点,直线,弧线等简单图形
- 一步步学Qt,第七天-QPainter绘图QRect定位问题
- QT 使用QPainter 绘制图形 和 世界变换 world transform
- 在Qt Widget中使用QPainter之外的引擎进行绘图
- 介绍MATLAB 的两种基本绘图功能:二维平面图形和三维立体图形
- HTML5之Canvas绘图——使用Canvas绘制图形的基本教程
- 【Visual C++】游戏开发笔记之四——游戏画面绘图(一)基本图形绘制
- Cairo 图形指南(1) —— 基本绘图
- 【Visual C++】游戏开发笔记之四——游戏画面绘图(一)基本图形绘制
- Qt QPainter绘图原理