Qt QWidget自定义绘制paintEvent导致的递归循环

#Qt QWidget自定义绘制 paintEvent导致的递归循环

最近在一个项目中遇到一个界面卡顿问题,现已解决,记录如下:

问题描述:

点击界面某个控件时,界面卡顿,调试发现父控件重载的paintEvent一直被循环调用,导致界面卡顿

原因:

在自定义控件QWidget中,重载的paintEvent函数中调用了子控件QLabel的update()函数。

在这里插入图片描述

void CustomWidget::paintEvent(QPaintEvent *event)
{
	label->update();
}

当子控件Qlabel 调用update重绘时,默认下会重绘背景,也就是QWidget的paintEvent会被调用,于是导致了递归循环

在这里插入图片描述

解决方法:

//给QLabel指定“WA_OpaquePaintEvent”属性,避免透明背景
label->setAttribute(Qt::WA_OpaquePaintEvent);

设置WA_OpaquePaintEvent 属性可以简单理解为,让本控件变得不透明,这样下层的控件图层不需要重绘来实现本控件的透明效果。

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_OpaquePaintEvent 属性指示控件当接收到绘制事件时,绘制每一个像素,它的使用提供了一个小的优化,在不支持双缓冲系统的系统上减少了闪烁,并且避免了在绘制之前擦除背景的计算周期。

可见该属性在控件、窗体重绘时避免了重绘背景、擦除本控件的消耗,带来性能的提升。

当然如果需要控件实现 “透明” 的效果就不要指定该属性,同时不要试图在自身的paintEvent中刷新或重绘任何上层控件

posted @ 2020-08-31 21:40  HL棣  阅读(17)  评论(0编辑  收藏  举报  来源