You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:45:49