Qt::WA_OpaquePaintEvent理解

Qt助手中对Qt::WA_OpaquePaintEvent解释如下:

Indicates that the widget paints all its pixels when it receives a paint event. Thus, it is not required for operations like updating, resizing, scrolling and focus changes to erase the widget before generating paint events. The use of WA_OpaquePaintEvent provides a small optimization by helping to reduce flicker on systems that do not support double buffering and avoiding computational cycles necessary to erase the background prior to painting. Note: Unlike WA_NoSystemBackground, WA_OpaquePaintEvent makes an effort to avoid transparent window backgrounds. This flag is set or cleared by the widget's author.

其含义大体是说:

 指示窗体在收到绘制事件时,绘制它的所有像素。因此,在收到绘制事件之前,对于更新、大小调整、滚动条滚动、焦点更变等操作时,并不要求窗体擦除窗体背景。使用该标志对那些不支持双缓冲区的系统提供了小小的优化,从而减小闪烁;同时避免在绘制之前因擦除背景需要计算而耗费时间。不同于WA_NoSystemBackground标志,WA_OpaquePaintEvent 尽量避免窗体背景透明,这个标志是由窗体的开发者设置或清除。

以上是Qt官方的解释。个人理解如下:

1): 指示窗体在收到绘制事件时,绘制它的所有像素。这里“收到绘制事件”个人理解应该是第一

          次收到绘制事件时,也即窗体构建时,就把窗体所有的像素绘制一遍。

2):窗体一旦在完成1)中说的绘制完一遍所有像素后,此后所有有关窗体的更新、大小改变,焦

         点改变、滚动条滚动等操作都不会擦除窗体背景。也就是说以前画的东西都不会擦除重绘。

         也就是以前画的不重新计算、不重新绘制。当以前绘制的东西很费时间时(如:某个曲线、

         某个图形是经过某个复杂的数学运算得出的),不重绘、不重新计算,这将节约很多cpu时间

         大大提高效率(这也就是设置本标志后,不闪烁的原因吧)。

一个设置Qt::WA_OpaquePaintEvent标志的例子如下:

#include "QtWidgetsApplication1.h"
#include<QPainter>

QtWidgetsApplication1::QtWidgetsApplication1(QWidget* parent)
    : QWidget(parent)
{
    ui.setupUi(this);
    setWindowTitle("parent");
}

QtWidgetsApplication1::~QtWidgetsApplication1()
{
    
}

void QtWidgetsApplication1::paintEvent(QPaintEvent* event)
{
  
    QPainter painter(this);
    for (int i = 0; i < 1000; ++i)
    {

        int r = qrand() % 255;
        int g = qrand() % 255;
        int b = qrand() % 255;

        QPen pen(qRgb(r, g, b));
        pen.setWidth(2);

        painter.setPen(pen);
        int x = qrand() % 800;
        int y = qrand() % 800;

        // 其实核心内容就是调用这一个函数而已
        painter.drawPoint(x, y);

    }

}

main函数如下:

#include "QtWidgetsApplication1.h"
#include <QtWidgets/QApplication>
#include<QTime>
#include<QThread>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QtWidgetsApplication1 w;
    w.show();
    w.setAttribute(Qt::WA_OpaquePaintEvent);
    QTime timer;
    {

        timer.start();

        // 调用此函数即相当于Windows中的GetMessage,系列函数,包括了tranlate,分发函数等的所有操作
       
        // 此处是控制帧数的关键点
        while (1)
        {
            a.processEvents();
            w.repaint();
            QThread::sleep(1);

        }

    }

    return a.exec();
}

运行后弹出窗体如下:

可以看到,窗体背景是黑色即不透明,因为不擦除背景即不擦除以前绘制的,故当第1次绘制事件发生时,绘制1000个点;第2次绘制事件发生时,再绘制1000个点,那么第N次后,绘制的总点数为1000*N个。当屏蔽掉上面main.cpp的如下代码:

w.setAttribute(Qt::WA_OpaquePaintEvent);

则窗体背景为正常颜色且每次绘制之前都会擦除以前绘制的,故N次后窗体依然只有1000个点,如下:

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值