簡體   English   中英

qt 5 如果我只想重繪 1 個小部件,如何防止重繪整個 window

[英]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 提供了兩種優化此行為的方法:

更多信息

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM