通过setAttribute函数可以对QWidget对象设置Qt::WidgetAttribute枚举属性或通过setWindowFlag、setWindowFlags函数对QWidget对象设置Qt::WindowType或Qt::WindowFlags属性,从而改变QWidget对象的某些特性。本篇博文讲解Qt::WA_StaticContents标识作用,对其它属性参见以下博文:
- Qt::WA_OpaquePaintEvent理解。
- Qt::WindowType、Qt::WidgetAttribute各个标志含义汇总。
- Qt::WA_QuitOnClose用法。
- Qt::WA_TransparentForMouseEvents用法。
- Qt::WA_NoMousePropagation用法。
Qt官方对Qt::WA_StaticContents解释如下:
Indicates that the widget contents are north-west aligned and static. On resize, such a widget will receive paint events only for parts of itself that are newly visible. This flag is set or cleared by the widget's author.
翻译为中文的意思就是:指示窗体内容靠西北方向即左上角对齐且是静态的。当窗体大小调整时,仅仅只有那些新露出来的可见窗体部分才会绘制。这个标识由窗体的开发者清除或设置。
下面举例子说明:
.h文件如下:
#pragma once
#include <QtWidgets/QWidget>
#include "ui_QtWidgetsApplication1.h"
#include<QTimer>
#include <QRandomGenerator>
class QtWidgetsApplication1 : public QWidget
{
Q_OBJECT
public:
QtWidgetsApplication1(QWidget *parent = nullptr);
~QtWidgetsApplication1();
void paintEvent(QPaintEvent* event);
private:
Ui::QtWidgetsApplication1Class ui;
QTimer* m_pChangeColorTimer{ nullptr }; // 改变颜色的定时器
QRandomGenerator m_rndColorGenerator; // 产生颜色的随机器
int m_nRed{ 255 }; // 颜色的红色分量值
int m_nGreen{ 0 }; // 颜色的绿色分量值
int m_nBlue{ 0 }; // 颜色的蓝色分量值
};
.cpp代码如下:
#include "QtWidgetsApplication1.h"
#include<QPainter>
#include<QDateTime>
#include<QDebug>
QtWidgetsApplication1::QtWidgetsApplication1(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
// 开启窗体静态内容属性
setAttribute(Qt::WA_StaticContents);
// 构建一个定时器,以便画刷颜色每1s钟改变一次
m_pChangeColorTimer = new QTimer(this);
m_pChangeColorTimer->setInterval(1000);
// 设置随机器的种子
auto seedTime = QDateTime::currentDateTime().currentMSecsSinceEpoch();
m_rndColorGenerator.seed(seedTime);
// 让定时器每隔1s生成一个随机颜色
connect(m_pChangeColorTimer, &QTimer::timeout, this, [=] {
m_nRed = m_rndColorGenerator.bounded(0, 256);
m_nGreen = m_rndColorGenerator.bounded(0, 256);
m_nBlue = m_rndColorGenerator.bounded(0, 256);
qInfo() << m_nRed << " " << m_nGreen << " " << m_nBlue << " ";
//update();
});
m_pChangeColorTimer->start();
}
QtWidgetsApplication1::~QtWidgetsApplication1()
{}
void QtWidgetsApplication1::paintEvent(QPaintEvent* event)
{
QPainter p(this);
p.setBrush(QBrush(QColor(m_nRed, m_nGreen, m_nBlue)));
p.drawEllipse(0, 100, 100, 100);
}
main.cpp如下:
#include "QtWidgetsApplication1.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QtWidgetsApplication1 w;
w.show();
return a.exec();
}
运行,效果如下:
图1
可以看到:当调大窗体尺寸时,原来已经处在窗体露出区域的圆没有重绘,还是保持以前颜色,窗体新露出部分所在圆使用新颜色重新绘制,而不是整个圆用新颜色重新绘制。
图2
图2的蓝色方框是原始窗体即未调大之前窗体,绿色方框是图2调大之后窗体。那么设置Qt::WA_StaticContents属性后,仅仅只有图2中的新露出部分发生重绘,原来已经绘制的圆部分不会重绘,即不会改变颜色。
通常情况下,当重新定义一个窗口部件大小时,Qt会为窗口部件的整个可见区域生成一个绘制事件。但是如果该窗口部件在创建时使用了Qt::WA_StaticContens属性,那么绘制事件的区域就会被严格限定在之前没有被显示最近刚露出的部分上。这也就意味着,如果重新把窗口部件改变为比原来还要小的尺寸,那么就根本不会产生任何绘制事件。这在某些情况下,可以提到性能,降低cpu效率,当以前绘制的东西很费时间时(如:某个曲线、某个图形是经过某个复杂的数学运算得出的),不重绘、不重新计算,这将节约很多cpu时间,大大提高效率。如下代码:
void QtWidgetsApplication1::paintEvent(QPaintEvent* event)
{
QPainter p(this);
auto nWidth = 100;
auto nHeight = 100;
for (auto x = 0; x < nWidth; ++x)
{
for (auto y = 0; y < nHeight; ++y)
{
int r = qrand() % 255;
int g = qrand() % 255;
int b = qrand() % 255;
QPen pen(qRgb(r, g, b));
pen.setWidth(2);
p.setPen(pen);
p.drawPoint(x, y);
}
}
}
当在QtWidgetsApplication1类的构造函数中,通过下面代码:
setAttribute(Qt::WA_StaticContents);
为窗体设置Qt::WA_StaticContents属性,在以同样速度、频率改变窗体大小同样尺寸时,设置该属性时的cpu占用率比不设置该属性的占用率低。尤其是当paintEvent函数是复杂的绘制时,性能更明显。当然,当你的需求是要绘制整个窗体时,Qt::WA_StaticContents就不适用了。