这两天在使用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. Java程序员必备基础:内部类解析

    前言 整理了一下内部类的相关知识,算是比较全,比较基础的,希望大家一起学习进步. 一.什么是内部类? 在Java中,可以将一个类的定义放在另外一个类的定义内部,这就是内部类.内部类本身就是类的一个属性 ...

  2. iSO垂直滑动条VerticalSlider

    由于项目需要实现一个垂直的Slider,滑动条使用UIlabel实现,按钮使用UIButton,按钮可以设置背景图片,代码如下 VerticalSlider.h // // VerticalSlide ...

  3. 重新认识C语言的指针(上)

    ​ 独创性并不是首次观察某种新事物,而是把旧的.很早就是已知的,或者是人人都视而不见的事物当新事物观察,这才证明是有真正的独创头脑 -尼采 本文已经收录至我的GitHub,欢迎大家踊跃star 和 i ...

  4. C语言之指针用法总结

    C语言指针概述:1.计算机系统中,无论是存入或是取出数据都需要与内存单元打交道,物理器件通过地址编码寻找内存单元.2.地址编码是一种数据,C语言的指针类型正是为了表示这种计算机所特有的地址数据.3.存 ...

  5. Mysql中使用mysqldump进行导入导出sql文件

    纪念工作中的第一次删库跑路的经历 今天接到一个任务,是将一个测试库数据导到另一个测试库,然而我们公司的数据库是不让直连的,所以只能通过远程连接进行导库操作. 老大布置任务的时候让用dump命令进行操作 ...

  6. map + 前缀和

    B. Balanced Substring time limit per test 1 second memory limit per test 256 megabytes input standar ...

  7. 《C# 爬虫 破境之道》:第二境 爬虫应用 — 第二节:以事件驱动状态、数据处理

    续上一节内容,对Web爬虫进行进一步封装,通过委托将爬虫自己的状态变化以及数据变化暴露给上层业务处理或应用程序. 为了方便以后的扩展,我先定义一个蚂蚁抽象类(Ant),并让WorkerAnt(工蚁)继 ...

  8. Java多线程的创建(二)

    前言: 虽然java的API中说创建多线程的方式只有两种(There are two ways to create a new thread of execution),分别是继承Thread类创建和 ...

  9. matplotlib 条形图

    一.特点 离散数据,数据之间没有直接的关系 二.分类 1.垂直条形图 bar(x, height, width=0.8) # x 为x轴 # height 为y轴 # width 为 条形图的宽度 例 ...

  10. java.lang.IllegalArgumentException: clusterListener can not be null

    Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.mongodb. ...