这两天在使用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 使用中出现的问题的更多相关文章

  1. Qt中绘图坐标QPainter,Viewport与Window的关系

    在Qt中常常要自己重载一些paintEvent函数,这个时候往往忽略了两个很关键的API,那就是setViewport和setWindow. Viewport,顾名思义,反应的是物理坐标,就是你实际想 ...

  2. Qt中在图片上叠加显示文字

    Qt中在图片上叠加显示文字   QCustLabel::QCustLabel(QWidget *parent):QLabel(parent){ setPixmap(QPixmap(QString::f ...

  3. Qt中使用信号和槽的一点心得

    信号(Signal)与槽(Slot)-Qt中的典型机制 这一篇文章中都说得很详细了,这里不再重复,只说一点在实际使用中可能会遇到的问题. 1.一个信号不要同时连接几个槽函数,不然执行的顺序是随机的,最 ...

  4. Qt入门(9)——Qt中的线程支持

    Qt对线程提供了支持,基本形式有独立于平台的线程类.线程安全方式的事件传递和一个全局Qt库互斥量允许你可以从不同的线程调用Qt方法.警告:所有的GUI类(比如,QWidget和它的子类),操作系统核心 ...

  5. Qt中截图功能的实现

    提要 需求:载入一张图片并显示,能够放大缩小,能够截取图片的某个矩形并保存. 原以为蛮简单的一个功能,事实上还是有点小复杂. 最简单Qt图片浏览器能够參考Qt自带的Demo:Image Viewer ...

  6. QT中事件处理器和事件过滤器实现实例

    Qt中事件处理的方式,最常用的就是使用事件处理器(event handler)和事件过滤器(event filter)这两种方法.接下来,我们就来看看事件处理器和事件过滤器是怎么使用的. 事件处理器 ...

  7. QT中设置窗口背景颜色

    QWidget是所有用户界面对象的基类,这意味着可以用同样的方法为其它子类控件改变背景颜色. Qt中窗口背景的设置,下面介绍三种方法. 1.使用QPalette 2.使用Style Sheet 3.绘 ...

  8. 【转载】Qt中图像的显示与基本操作

    Qt可显示基本的图像类型,利用QImage.QPxmap类可以实现图像的显示,并且利用类中的方法可以实现图像的基本操作(缩放.旋转). 参考:Qt中图像的显示与基本操作 - ykm0722的专栏 - ...

  9. Qt中的QTableView 中的列放入Widget

    QTableView是Qt中Model View理念的框架,View只展现数据,所以通过互交修改编辑数据,需要用到委托这个概念Delegate. 所以基本思路是继承QItemDelegate这个类,然 ...

随机推荐

  1. Queue and deque

    Queue : 队列 队列(Queue)是常用的数据结构,可以将队列看成特殊的线性表,队列限制了对线性表的访问方式:只能从线性表的一端添加(offer)元素,从另一端取出(poll)元素. 队列遵循先 ...

  2. ArcEngine 创建线要素图层

    在创建要素图层的时候,默认的几何类型是Polygon: Dim objectClassDescription As IObjectClassDescription = New FeatureClass ...

  3. ILSpy反编译工具之C#反汇编

    1.下载ILspy工具 https://github.com/icsharpcode/ILSpy#ilspy------- 注意: ILspy需要在电脑上安装.NET Framework 4.0.   ...

  4. Spring Cloud(二):Web服务客户端之Ribbon

    上文介绍了服务如何通过Eureka实现注册,以及如何从Eureka获取已经注册的服务列表.那么拿到注册服务列表后, 如何进行服务调用?一个简单的实现是可以从被调用服务的实例列表中选择一个服务实例,通过 ...

  5. 字符串转hash进阶版

    #include<bits/stdc++.h> using namespace std; ,mod=; vector<unsigned> H[mod]; void Add(un ...

  6. win10关闭系统更新 (转载)

    一.关闭Windows10系统的自动更新服务 1:使用快捷键Win+R,打开运行 2:输入命令:services.msc,打开系统服务界面 找到Windows Update双击 将启动类型改为[禁用] ...

  7. 在 ASP.NET Core 程序启动前运行你的代码

    一.前言 在进行 Web 项目开发的过程中,可能会存在一些需要经常访问的静态数据,针对这种在程序运行过程中可能几乎不会发生变化的数据,我们可以尝试在程序运行前写入到缓存中,这样在系统后续使用时就可以直 ...

  8. Oracle RAC服务器重启故障排查

    Oracle Real Application Clusters(Oracle RAC),相对于Oracle单实例来说部署安装和维护都增加了难度,尤其在日常的维护和故障处理过程中,各种日志的查看更加重 ...

  9. docker安装的gitlab的备份与恢复

    1.对docker容器安装gitlab备份 1) 查看容器id docker ps 2) 将容器备份成镜像文件 docker commit -a 'James' -m 'gitlab_backup' ...

  10. 保存数据到txt

    join用的不错 a = "Hello, world" b = "你好,世界" c = "How are you?" with open(f ...