Qt 中QPainter 使用中出现的问题
这两天在使用QPainter的过程中出现了一些问题,记录一下。
测试程序很简单,写一个继承自QWidget的类,重载其paintEvent函数进行绘图。

case1:
在paintEvent函数中使用一个临时的painter对象进行绘制。

结果:能够正常绘制。
case2:
在paintEvent函数中动态分配一个painter对象进行绘制。

结果:能够正常绘制。
case3:将Painter声明为一个类的成员变量进行绘制。



结果:不能正常绘制

分析:由于我在初始化m_painter时,用到的是QPainter m_painter(this);
这句代码等于QPainter m_painter,m_painter.begin(this);
但是m_painter.begin()函数只有在paintEvent()函数中调用才是有意义的(Qt中的绘制动作只能在paintEvent()函数中完成)
由于此时begin()函数隐式在构造函数中被调用了,最终倒是绘图动作失效。
试探的解决办法:在用不带参数的构造函数初始化painter,然后再paintEvent函数中利用begin函数为painter绑定对象。


试探的解决方法的结果;窗体先是正常绘制,接着就崩溃了,并报出如下错误:

我原本的思路是:当MyWidget对象析构是,就会自动调用其内部成员变量painter的析构函数,所以我就没有显式的嗲用end()函数,因为我希望painter对象能够在MyWidget的声明周期中一直存在。
结果:程序提醒我在绘制完成后必须调用end()函数,难道QPainter对象是一个一次性消耗品,用完一次就得扔?
果然,当加上end()代码后,程序就没问题了。

但是,调用end()函数中,m_painter对象就等于析构了。当我第二次进行绘制动作时,会不会出现问题?
结果是并不会,因此当进行隐藏以及重现窗体,更改窗体大小这些动作时(这些动作都会触发窗体的重绘操作),窗体并没有崩溃。
这里我有点疑惑,难道时begin()函数为m_painter重新分配了资源?可按理来说,已经析构的对象时无法再次使用的。。
Qt的文档上并没有相关的解答。


总之:从这个例子中我可以体会到painter的构造析构函数与begin()end()函数是有区别的。
case4:以一个QPainter对象的指针作为类成员变量,为这个指针分配资源。
如是在构造函数中以带参数的构造函数来初始化QPainter对象,依然会出现上面的错误。



一个尝试:我故意不用end()函数结束绘制,而选择delete掉m_painter;

程序果然崩溃了:
总结:end()函数和delete是有区别的,end()之后还能再begin(),在delete之后,该对象就彻底消失了。
小小感触:最好还是将QPainter对象当成一个一次消耗品来用吧,即在需要绘图时创建一个临时的QPainter对象来进行绘制。
Qt 中QPainter 使用中出现的问题的更多相关文章
- Qt中绘图坐标QPainter,Viewport与Window的关系
在Qt中常常要自己重载一些paintEvent函数,这个时候往往忽略了两个很关键的API,那就是setViewport和setWindow. Viewport,顾名思义,反应的是物理坐标,就是你实际想 ...
- Qt中在图片上叠加显示文字
Qt中在图片上叠加显示文字 QCustLabel::QCustLabel(QWidget *parent):QLabel(parent){ setPixmap(QPixmap(QString::f ...
- Qt中使用信号和槽的一点心得
信号(Signal)与槽(Slot)-Qt中的典型机制 这一篇文章中都说得很详细了,这里不再重复,只说一点在实际使用中可能会遇到的问题. 1.一个信号不要同时连接几个槽函数,不然执行的顺序是随机的,最 ...
- Qt入门(9)——Qt中的线程支持
Qt对线程提供了支持,基本形式有独立于平台的线程类.线程安全方式的事件传递和一个全局Qt库互斥量允许你可以从不同的线程调用Qt方法.警告:所有的GUI类(比如,QWidget和它的子类),操作系统核心 ...
- Qt中截图功能的实现
提要 需求:载入一张图片并显示,能够放大缩小,能够截取图片的某个矩形并保存. 原以为蛮简单的一个功能,事实上还是有点小复杂. 最简单Qt图片浏览器能够參考Qt自带的Demo:Image Viewer ...
- QT中事件处理器和事件过滤器实现实例
Qt中事件处理的方式,最常用的就是使用事件处理器(event handler)和事件过滤器(event filter)这两种方法.接下来,我们就来看看事件处理器和事件过滤器是怎么使用的. 事件处理器 ...
- QT中设置窗口背景颜色
QWidget是所有用户界面对象的基类,这意味着可以用同样的方法为其它子类控件改变背景颜色. Qt中窗口背景的设置,下面介绍三种方法. 1.使用QPalette 2.使用Style Sheet 3.绘 ...
- 【转载】Qt中图像的显示与基本操作
Qt可显示基本的图像类型,利用QImage.QPxmap类可以实现图像的显示,并且利用类中的方法可以实现图像的基本操作(缩放.旋转). 参考:Qt中图像的显示与基本操作 - ykm0722的专栏 - ...
- Qt中的QTableView 中的列放入Widget
QTableView是Qt中Model View理念的框架,View只展现数据,所以通过互交修改编辑数据,需要用到委托这个概念Delegate. 所以基本思路是继承QItemDelegate这个类,然 ...
随机推荐
- Python开发 之 Websocket 的使用示例
1.唠唠叨叨 最近又回顾了下Websocket,发现已经忘的七七八八了.于是用js写了客户端,用python写了服务端,来复习一下这方面的知识. 2.先看一下效果吧 2.1.效果1(一个客户端连上服务 ...
- APICloud发布低代码开发平台
云原生的出现,致使传统IT模式正在集中向云架构.云开发转型,其中在企业业务的互联网化.数字化进程中尤为突出,并衍生出“敏捷开发”.“快速迭代”的刚性需求.面对双模IT,如何打造全新的IT团队与模式?并 ...
- python 生成器 yield语句
生成器就是一个返回迭代器(iterator)的函数. 包含了 yield 的函数,就是一个生成器. 生成器每使用yield语句产生一个值,函数就会被冻结(暂停执行),被唤醒后(即再次调用)接着上次执行 ...
- dp-完全背包(题)
理解了这道题 , 我感觉对背包又有了一个更深的认识 …… HDU 2159 最近xhd正在玩一款叫做FATE的游戏,为了得到极品装备,xhd在不停的杀怪做任务.久而久之xhd开始对杀怪产生的厌恶感, ...
- sql if else 语句
IF ELSE 语句IF ELSE 是最基本的编程语句结构之一几乎每一种编程语言都支持这种结构而它在用于对从数据库返回的数据进行检查是非常有用的TRANSACT-SQL 使用IF ELSE的例子如下语 ...
- Akka Java 文档 -- 容错
[转自: http://blog.csdn.net/zjw10wei321/article/details/46911825] 容错 实际中的故障处理 容错案例图解 容错案例所有源码 创建新的监管策略 ...
- 类选择器练习:Google 案例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...
- [apue] 一个查看当前终端标志位设置的小工具
话不多说,先看运行效果: >./term input flag 0x00000500 BRKINT not in ICRNL IGNBRK not in IGNCR not in IGNPAR ...
- spring-cloud-gateway报错
2019-08-13 09:41:19.216 WARN [-,,,] 10084 --- [ main] ConfigServletWebServerApplicationContext : Exc ...
- GoldenGate DB11gr2配置手册
GoldenGate DB11gr2配置手册 源端数据库配置 1.1源端数据库打开Archive Log: SQL>shutdown immediate; SQL>startup moun ...