c++ 什么时候Qt小部件得到一个paintEvent?

我想知道一个小部件在哪些情况下接收到它的paint事件,并且它随操作系统而变化.

仅适用于paintEvent的Qt文档

A paint event is a request to repaint all or part of a widget. It can happen for one of the following reasons:

repaint() or update() was invoked,

the widget was obscured and has now been uncovered, or

many other reasons.

到目前为止,我已经在paintEvent中放了一些痕迹,

void Widget::paintEvent(QPaintEvent *e)
{
    static int count = 0;
    qDebug("paintEvent, %d", count++);
}

这是我发现的(至少在Windows 7上):

当小部件失去/获得焦点时,调用paintEvent.当另一个窗口小部件通过我们的窗口小部件时,paint事件不会被调用.我不知道是不是因为Windows 7的合成.当恢复最小化的窗口时,也会调用paintEvent.调整大小时调用paintEvent.

行为依赖于操作系统吗?

最佳答案
是的,在你描述的意义上,它取决于操作系统.

桌面窗口管理器(DWM),在Windows Vista和7中,负责桌面组合,Aero玻璃效果和各种其他眼睛糖果的doohickey与以前版本的Windows中使用的模型有所不同.您怀疑,它缓存了Windows的位图,即使它们不可见,因为它们被另一个窗口遮挡.这意味着它不需要您重绘它们(因此它不会引发paint事件),因为它可以将它们从缓存的位图中删除.这不仅使每个应用程序重新绘制都是一个潜在的优化,它还允许DWM实现像Aero Flip这样的东西,它使用它的缓存位图.

这是例外,就像CS_SAVEBITS类样式一直以来一样.如果DWM缓存的位图已经失效(例如,因为您的窗口图像已更改),则会丢弃它,并要求您重新绘制窗口.

通过关闭DWM组合(切换到“Windows Classic”主题)来测试此理论,然后遮蔽您的窗口以查看是否收到绘画事件.你应该像以前所有Windows版本一样.

但更重要的是,您不应该依赖任何特定顺序的油漆事件.你应该假设绘画事件的唯一的事情是,当操作系统需要重新绘制窗口时,您将收到一个.否则,它不会打扰你.我确信这就是为什么文档在这一点上是含糊不清的,超出了可能的技术限制.

这就是为什么逻辑不应该在paint事件处理程序的内部.该方法唯一应该负责的是通过其当前状态重新绘制窗口.那个国家需要保存在别的地方.这个规则也是可交换的:你不应该在paint事件处理程序之外做任何绘画.

当然,您总是可以通过使窗口无效来强制绘制事件(我确定Qt有一个无效或刷新方法,检查文档),但这并不意味着它是一个很好的模式放置处理此事件的方法中的应用程序逻辑.

转载注明原文:c++ 什么时候Qt小部件得到一个paintEvent? - 代码日志