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这个类,然 ...
随机推荐
- Have Fun with Numbers
Notice that the number 123456789 is a 9-digit number consisting exactly the numbers from 1 to 9, wit ...
- ZooKeeper Java Example
A Simple Watch Client Requirements Program Design The Executor Class The DataMonitor Class Complete ...
- Java五子棋小游戏(控制台纯Ai算法)
Java五子棋小游戏(控制台纯Ai算法) 继续之前的那个五子棋程序 修复了一些已知的小Bug 这里是之前的五子棋程序 原文链接 修复了一些算法缺陷 本次增加了AI算法 可以人机对战 也可以Ai对Ai看 ...
- 你知道Java中的CopyOnWriteArrayList吗?
CopyOnWrite CopyOnWrite是什么? CopyOnWriteArrayList源码分享? CopyOnWriteArrayList使用场景? CopyOnWriteArrayList ...
- php获取本年、本月、本周时间戳和日期格式
时间戳格式: //获取今日开始时间戳和结束时间戳 $beginToday=mktime(0,0,0,date('m'),date('d'),date('Y')); $endToday=mktime(0 ...
- 安装mysql8.0.17指南
1.首先,下载社区版mysql(下载地址https://dev.mysql.com/downloads/mysql/) 2.下载之后,将文件解压到自己想要安装的目录(如,本人将解压文件放置g://my ...
- ChoiceFiled MultipleChoiceField ModelChoiceField ModelMultipleChoiceField
1.ChoiceFiled 单选 字段 2.MultipleChoiceField 多选 3.ModelChoiceField 单选 query_set 4.ModelMultipleChoiceFi ...
- Qt Installer Framework翻译(6-0)
Qt安装程序框架示例 这些示例说明了如何使用组件脚本来自定义安装程序. Change Installer UI Example 使用组件脚本修改安装程序UI. Component Error Exam ...
- [bzoj3938] [Uoj #88] Robot
Description 小 \(q\) 有 \(n\) 只机器人,一开始他把机器人放在了一条数轴上,第 \(i\) 只机器人在 \(a_i\) 的位置上静止,而自己站在原点.在这之后小 \(q\) 会 ...
- 13、python的路径处理
前言:本文主要介绍python中路径的处理,包括os模块和有关的2个魔法变量. 一.os模块 python里面的os模块有许多方法可以让我们通过代码实现创建,删除和更改目录,具体如下: os.getc ...