zoukankan      html  css  js  c++  java
  • 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对象来进行绘制。

  • 相关阅读:
    shader之渐变长方体实现(threejs)
    shader之threejs应用
    shader之cesium应用
    pip install -- Failed building wheel for XXX
    pycharm -- 界面乱码
    Android Studio -- 优化速度
    django -- ImageField 上传图片修改头像
    AI -- 回溯法解决四皇后问题
    Android Studio -- 真机测试
    傻瓜函数式编程
  • 原文地址:https://www.cnblogs.com/XiaoXiaoShuai-/p/12201324.html
Copyright © 2011-2022 走看看