Qt:子部件光标闪烁为何触发父部件重绘?
为什么QLineEdit光标闪烁会触发父部件MyW的paintEvent?
这个问题的核心在于Qt的窗口重绘机制和部件属性设置,我来给你拆解清楚:
你的MyW作为自定义QWidget,默认既没开启Qt::WA_OpaquePaintEvent属性,autoFillBackground也是关闭状态。当QLineEdit的光标闪烁时,它会每秒重绘自己的光标区域——这是正常行为,但Qt此时会认为父部件(MyW)在子部件下方的区域可能需要重新绘制,因为它不确定父部件是否已经完全不透明地填充了整个区域,所以就会频繁触发MyW的paintEvent。
解决方法
你只需要给MyW添加一个属性声明,告诉Qt这个部件会完全填充自己的区域,不需要额外的背景填充操作就行:
修改你的MyW构造函数:
MyW() { // 告诉Qt该部件会完全绘制整个区域,无透明部分 setAttribute(Qt::WA_OpaquePaintEvent); }
或者另一种等效方式,开启自动填充背景:
MyW() { setAutoFillBackground(true); }
原理说明
Qt::WA_OpaquePaintEvent属性会让Qt明确:这个部件的paintEvent会完全覆盖整个部件区域,没有任何透明或未绘制的部分。这样当子部件重绘时,Qt就不需要触发父部件的重绘来补充背景了。- 开启
autoFillBackground的话,Qt会自动帮你填充部件的背景,同样能避免因为子部件重绘而触发父部件的paintEvent。
修改后再运行代码,你会发现只有在窗口初始化、调整大小等必要场景下才会输出paintEvent,光标闪烁时不会再频繁触发父部件的重绘了。
你的测试代码我也整理在这里方便参考:
#include <QApplication> #include <QWidget> #include <QPaintEvent> #include <QPainter> #include <QLineEdit> class MyW final : public QWidget { public: MyW() { setAttribute(Qt::WA_OpaquePaintEvent); //setAutoFillBackground(true); } void paintEvent(QPaintEvent *e) { e->accept(); qDebug("paintEvent"); QPainter painter{this}; painter.fillRect(rect(), Qt::green); } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); MyW w; w.resize(600, 600); w.show(); auto le = new QLineEdit{&w}; le->show(); return app.exec(); }
内容的提问来源于stack exchange,提问作者user1244932
相关产品推荐
相关产品推荐

