Qt学习笔记之2D绘图 逃离我推掉我的手 2023-07-05 10:05 17阅读 0赞 # 一、概要 # Qt中提供了强大的2D绘图系统,可以使用相同的API在屏幕和绘图设备上进行绘制,它主要基于`QPainter`、`QPaintDevice`和`QPaintEngine`这三个类。其中`QPainter`用来执行绘图操作;`QPaintDevice`提供绘图设备,它是一个二维空间的抽象,可以使用`QPainter`在其上进行绘制;`QPaintEngine`提供了一些接口,可以用于`QPainter`在不同的设备上进行绘制。 QPaintEngine类由QPainter和QPaintDevice内部使用,应用程序一般无需和QPaintEngine打交道,除非要创建自己的设备类型。 在绘图系统中由`QPainter`来完成具体的绘制操作,`QPainter`类提供了大量高度优化的函数来完成GUI编程所需要的大部分绘制工作。`QPainter`可以绘制一切想要的图形,从最简单的一条直线到其他任何复杂的图形,它还可以用来绘制文本和图片。`QPainter`可以在继承自`QPaintDevice`类的任何对象上进行绘制操作。 `QPainter`一般在一个部件的重绘事件(`Paint Event`)的处理函数`paintEvent()`中进行绘制,首先要创建`QPainter`对象,然后进行图形的绘制,最后销毁`QPainter`对象。 注:从QWidget类继承的类都有paintEvent()事件,要在设备上绘图,只需要重写此事件函数,并在函数内编写相应的绘图代码就可以了,一般的绘图设备包括QWidget、QPixmap、QImage等,这些绘图设备为QPainter提供了一个“画布”,QPainter可以在这些设备上进行绘图。 # 二、窗口各类位置相关函数的区别 # ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2E4MDM5OTc0_size_16_color_FFFFFF_t_70][] 其中: * x()、y()和pos()函数都是获得整个窗体左上角的坐标位置。 * frameGeometry()与geometry()相对应。frameGeometry()是获得整个窗体的左上顶点和长、宽值,而geometry()函数获得的是窗体内中央区域的左上顶点坐标以及长、宽值。 * 直接调用width()和height()函数获得的是中央区域的长、宽值。 * rect()、size()函数获得的结果也都是对于窗体的中央区域而言的。size()获得的是窗体中央区域的长、宽值,rect()与geometry()一样返回一个QRect对象,这两个函数获得的长、宽值是一样的,都是窗体中央区域的长、宽值,只是左上顶点的坐标值不一样,geometry()获得的左上顶点坐标是相对于父窗体而言的坐标,而rect()获得的左上顶点坐标始终为(0,0)。在实际应用中需根据情况使用正确的位置信息函数以获得准确的位置尺寸信息,尤其是在编写对位置精度要求较高的程度时(如地图浏览程序),更应注意函数的选择,避免产生不必要的误差。 # 三、绘图操作的一般步骤 # 方式1: QPainter painter(this) //! 配置相关属性 setPen(); //设置画笔, setFont(); //设置字体格式 setBrush(); //设置画刷 setRenderHint(QPainter::Antialiasing); //设置反锯齿 //设置组合模式,即后面绘制的图与前面绘制的图叠加模式,参数是一个QPainter::CompositionMode枚举类型(类型很多,有40多种,详情见QT帮助文档) void QPainter::setCompositionMode(CompositionMode mode) 绘图操作 方式2 QPainter painter; painter.begin(this); //! 配置相关属性 setPen(); //设置画笔, setFont(); //设置字体格式 setBrush(); //设置画刷 setRenderHint(QPainter::Antialiasing); //设置反锯齿 //设置组合模式,即后面绘制的图与前面绘制的图叠加模式,参数是一个QPainter::CompositionMode枚举类型(类型很多,有40多种,详情见QT帮助文档) void QPainter::setCompositionMode(CompositionMode mode) 绘图操作 painter.end(); # 四、一般绘图演示 # void Widget::paintEvent(QPaintEvent *event) { QPainter painter(this); //! 添加画笔 QPen pen; pen.setColor( QColor(255,0,0) ); pen.setStyle(Qt::DotLine); pen.setWidth(2); painter.setPen(pen); //! 添加画刷 QBrush brush; brush.setColor(QColor(0,255,0,125)); brush.setStyle(Qt::SolidPattern); painter.setBrush(brush); //! 画矩形框 painter.drawRect(10,20,200,100); //! 画直线 painter.drawLine(QPoint(0,0),QPoint(100,100)); } 输出结果: ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2E4MDM5OTc0_size_16_color_FFFFFF_t_70 1][] # 五、显示文字演示 # void Widget::paintEvent(QPaintEvent *event) { QPainter painter(this); //! 添加画笔 QPen pen; pen.setColor( QColor(255,0,0) ); pen.setStyle(Qt::DotLine); pen.setWidth(2); painter.setPen(pen); //! 添加画刷 QBrush brush; brush.setColor(QColor(0,255,0,125)); brush.setStyle(Qt::SolidPattern); painter.setBrush(brush); //! 画矩形框 painter.drawRect(10,20,200,100); //! 画直线 painter.drawLine(QPoint(0,0),QPoint(100,100)); //! 设置字体 QFont font; font.setFamily("宋体"); font.setPixelSize(10); font.setBold(true); font.setUnderline(true); font.setLetterSpacing(QFont::AbsoluteSpacing,1); painter.setFont(font); //! 绘制文字 painter.drawText(QPoint(100,100),"你好"); painter.drawText(QRect(10,20,200,100),Qt::AlignCenter,"你好"); } ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2E4MDM5OTc0_size_16_color_FFFFFF_t_70 2][] # 六、显示图片演示 # Qt提供了四个类来处理图像数据:`QImage`、`QPixmap`、`QBitmap`和`QPicture`,它们也都是常用的绘图设备。其中`QImage`主要用来进行I/O处理,它对I/O处理操作进行了优化,而且也可以用来直接访问和操作像素;`QPixmap`主要用来在屏幕上显示图像,它对在屏幕上显示图像进行了优化;`QBitmap`是`QPixmap`的子类,它是一个便捷类,用来处理颜色深度为1的图像,即只能显示黑白两种颜色;`QPicture`用来记录并重演`QPainter`命令。 void Widget::paintEvent(QPaintEvent *event) { QPainter painter(this); QPixmap pix; pix.load("E:/work/qe/myGui3/1.png"); painter.drawPixmap(QRect(0,0,pix.width(),pix.height()),pix); } ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2E4MDM5OTc0_size_16_color_FFFFFF_t_70 3][] # 七、绘制路径演示 # 如果要绘制一个复杂的图形,尤其是要重复绘制这样的图形,那么可以使用`QPainterPath`类,然后使用`QPainter::drawPath()`来进行绘制。`QPainterPath`类为绘制操作提供了一个容器,可以用来创建图形并且重复使用。一个绘图路径就是由多个矩形、椭圆、线条或者曲线等组成的对象,一个路径可以是封闭的,例如矩形和椭圆;也可以是非封闭的,例如线条和曲线。 void MainWidget::paintEvent(QPaintEvent *event) { //! 设置字体 QFont font; font.setFamily("宋体"); font.setPixelSize(64); font.setBold(true); font.setUnderline(true); QPainterPath painterPath; painterPath.addRect(QRect(20,20,200,200)); painterPath.moveTo(200,200); painterPath.lineTo(300,400); painterPath.addText(QPoint(300,400),font,"你好"); QPainter painter; painter.begin(this); //! 设置画笔 QPen pen; pen.setWidth(1); pen.setStyle(Qt::DotLine); pen.setColor(QColor(255,0,0)); painter.setPen(pen); //! 设置画刷 QBrush brush; brush.setColor(QColor(0,255,0,125)); brush.setStyle(Qt::SolidPattern); painter.setBrush(brush); painter.drawPath(painterPath); painter.end(); } # 八、双缓冲绘图演示 # 双缓冲(double-buffers)绘图,就是在进行绘制时,先将所有内容都绘制到一个绘图设备(如`QPixmap`)上,然后再将整个图像绘制到部件上显示出来。使用双缓冲绘图可以避免显示时的闪烁现象。从Qt 4.0开始,`QWidget`部件的所有绘制都自动使用了双缓冲,所以一般没有必要在`paintEvent()`函数中使用双缓冲代码来避免闪烁。 虽然在一般的绘图中无需手动使用双缓冲绘图,不过要想实现一些绘图效果,还是要借助于双缓冲的概念。比如这个程序里,我们要实现使用鼠标在界面上绘制一个任意大小的矩形。这里需要两张画布,它们都是`QPixmap`实例,其中一个`tempPix`用来作为临时缓冲区,当鼠标正在拖动矩形进行绘制时,将内容先绘制到`tempPix`上,然后将`tempPix`绘制到界面上;而另一个`pix`作为缓冲区,用来保存已经完成的绘制。当松开鼠标完成矩形的绘制后,则将`tempPix`的内容复制到pix上。为了绘制时不显示拖影,而且保证以前绘制的内容不消失,那么在移动鼠标过程中,每绘制一次,都要在绘制这个矩形的原来的图像上进行绘制,所以需要在每次绘制`tempPix`之前,先将pix的内容复制到`tempPix`上。因为这里有两个`QPixmap`对象,也可以说有两个缓冲区,所以称之为双缓冲绘图。 代码详见《[双缓冲绘图练习(20200217)][20200217]》 # 九、图形视图框架 # # 十、绘制波形图 # 参考资料: 1. [http://shouce.jb51.net/qt-beginning/15.html][http_shouce.jb51.net_qt-beginning_15.html] 2. [QT基础:45---QPainter绘图][QT_45---QPainter] 3. [Qt之图形(QPainterPath)][Qt_QPainterPath] 4.[QT基础:46---QPainter绘图之QPen、QBrush、QFont工具][QT_46---QPainter_QPen_QBrush_QFont] 5.[mouseMoveEvent中判断鼠标状态][mouseMoveEvent] 6.[QT基础:47---QPainter绘图之坐标转换函数、视口和窗口][QT_47---QPainter] [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2E4MDM5OTc0_size_16_color_FFFFFF_t_70]: https://img-blog.csdnimg.cn/20200213170258496.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2E4MDM5OTc0,size_16,color_FFFFFF,t_70 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2E4MDM5OTc0_size_16_color_FFFFFF_t_70 1]: https://img-blog.csdnimg.cn/20200213225229258.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2E4MDM5OTc0,size_16,color_FFFFFF,t_70 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2E4MDM5OTc0_size_16_color_FFFFFF_t_70 2]: https://img-blog.csdnimg.cn/20200213230723588.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2E4MDM5OTc0,size_16,color_FFFFFF,t_70 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2E4MDM5OTc0_size_16_color_FFFFFF_t_70 3]: https://img-blog.csdnimg.cn/20200213231849141.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2E4MDM5OTc0,size_16,color_FFFFFF,t_70 [20200217]: https://blog.csdn.net/a8039974/article/details/104340559 [http_shouce.jb51.net_qt-beginning_15.html]: http://shouce.jb51.net/qt-beginning/15.html [QT_45---QPainter]: https://blog.csdn.net/qq_41453285/article/details/100040518 [Qt_QPainterPath]: http://blog.csdn.net/liang19890820/article/details/51393152 [QT_46---QPainter_QPen_QBrush_QFont]: https://blog.csdn.net/qq_41453285/article/details/100040781 [mouseMoveEvent]: https://blog.csdn.net/vXueYing/article/details/86717660 [QT_47---QPainter]: https://blog.csdn.net/qq_41453285/article/details/100046564
相关 Qt学习笔记之2D绘图 一、概要 Qt中提供了强大的2D绘图系统,可以使用相同的API在屏幕和绘图设备上进行绘制,它主要基于`QPainter`、`QPaintDevice`和`QPaintEn 逃离我推掉我的手/ 2023年07月05日 10:05/ 0 赞/ 18 阅读
相关 【Qt】2D绘图之双缓冲绘图 00. 目录 文章目录 00. 目录 01. 概述 02. 开发环境 03. 绘制矩形 04. 青旅半醒/ 2022年11月13日 00:48/ 0 赞/ 246 阅读
相关 【Qt】2D绘图之涂鸦板 00. 目录 文章目录 00. 目录 01. 概述 02. 开发环境 03. 程序设计(基本功能) Dear 丶/ 2022年11月12日 15:59/ 0 赞/ 198 阅读
相关 【Qt】2D绘图之绘图中其它问题 00. 目录 文章目录 00. 目录 01. 概述 02. 开发环境 03. 重绘事件 04. 怼烎@/ 2022年11月12日 14:57/ 0 赞/ 218 阅读
相关 【Qt】2D绘图之绘制图片 00. 目录 文章目录 00. 目录 01. 概述 02. 开发环境 03. 简单绘制图片 04 - 日理万妓/ 2022年11月12日 10:58/ 0 赞/ 239 阅读
相关 【Qt】2D绘图之坐标系统 00. 目录 文章目录 00. 目录 01. 概述 02. 开发环境 03. Qt坐标系统 04 约定不等于承诺〃/ 2022年11月12日 09:52/ 0 赞/ 230 阅读
相关 【Qt】2D绘图之渐变填充 00. 目录 文章目录 00. 目录 01. 概述 02. 开发环境 03. 线性渐变 04. 刺骨的言语ヽ痛彻心扉/ 2022年11月12日 09:45/ 0 赞/ 257 阅读
相关 学习笔记之Qt4的2D绘图 1. Qt4中的2D绘图部分称为Arthur绘图。它由3个主要的类支撑起整个框架: (1) QPainter:用来执行具体的绘画操作。 (2) QPa 爱被打了一巴掌/ 2022年07月12日 16:25/ 0 赞/ 274 阅读
还没有评论,来说两句吧...