[英]qt 5 how to prevent repaint whole window if i want repaint only 1 widget
最小代碼示例:
class Boo : public QPushButton{
public:
Boo(QWidget* w) : QPushButton(w){}
virtual void paintEvent(QPaintEvent* ev){
qDebug()<<__FUNCTION__<<this->objectName();
}
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
virtual void paintEvent(QPaintEvent* ev){
qDebug()<<__FUNCTION__;
}
private:
QTimer t;
Ui::MainWindow *ui;
Boo *b1, *b2;
};
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
b1 = new Boo(this);
b1->setObjectName("O1");
b2 = new Boo(this);
b2->setObjectName("O2");
connect(&t, &QTimer::timeout, this, [this](){
b2->repaint();
});
t.start();
t.setInterval(10);
}
無限輸出: MainWindow::paintEvent Boo::paintEvent "O1" Boo::paintEvent "O2"
但我只為按鈕 b2 調用重繪。 使用 "QWidget::repaint(int x, int y, int w, int h)" 或:QWidget::update()" 也調用主 window 的重繪。
Qt5.12/5.15 和 windows11 上存在問題,但看起來像一般的 qt 錯誤。
在我們更復雜的 GUI 應用程序中,此問題會導致 GPU 消耗較高。
好的。 我自己找到了原因,添加后:
...
b1->setGeometry(15,15, 12, 12);
...
b2->setGeometry(35,35, 14, 14);
...
virtual void paintEvent(QPaintEvent* ev){
qDebug()<<__FUNCTION__<<ev->rect();
}
輸出說,實際重繪僅對按鈕區域進行:
MainWindow::paintEvent QRect(35,35 14x14) Boo::paintEvent "O2" QRect(0,0 14x14)
重要的事情:為按鈕調用 setGeometry,而不僅僅是添加為子項。 在其他情況下(當然,僅可用於玩具示例)具有未設置幾何圖形的重繪按鈕將導致重新繪制具有未設置幾何圖形的每個按鈕。
Qt 默認情況下也會重繪所有父級,以允許小部件部分透明。 如果 Qt 沒有在更新時重新繪制父級,則前一個paintEvent
的某些像素可能仍然可見。
當不需要透明背景時,Qt 提供了兩種優化此行為的方法:
autoFillBackground
。 在不透明背景顏色的情況下,此選項是首選。Qt::WA_OpaquePaintEvent
以指示您將繪制整個小部件(使用不透明顏色)。更多信息
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.