簡體   English   中英

調整大小時閃爍的白色區域 Qt window

[英]flickering white areas when resizing Qt window

我在調整QWindow大小時觀察到一種奇怪的行為。 當我調整 window 的大小以使寬度和高度都增加或減少時,window 不會在白色背景下閃爍。 但是當我在減小高度的同時增加寬度(反之亦然)時,window 會閃爍並暫時用白色填充新區域。 這是一個非常煩人的效果,尤其是當我的應用程序中有一個深色主題並且我調整了 window 的大小時。

為了對此進行試驗,我使用了捆綁在 Qt SDK 中的“rasterwindow”示例。 這不使用QtWidgets ,所以我使用了這個示例,以便排除效果是由小部件引起的。 我添加了QThread::msleep(100); RasterWindow::render(QPainter *) function 來模擬非常慢的渲染。 然后我嘗試調整 window 的大小。 我只能在 Windows 上觀察到這一點,但不能在 Linux 或 Mac 上觀察到。 請參閱隨附的 GIF。

我的問題:

  1. 知道是什么導致了問題嗎? 為什么只在 Windows 上?
  2. 為什么在增加寬度和高度時無法觀察到它? 為什么在減少一個維度並增加另一個維度時會觀察到它?
  3. 如何擺脫它?
  4. 如果我不能完全擺脫它,我可以用白色以外的其他顏色填充新區域(這樣在深色主題中就不會那么煩人了)?

在此處輸入圖像描述

更新:我在這里創建了簡約示例

/*
This is a minimalistic example to show Qt window flickering on Windows (not observed on Linux nor MacOS).

This is observable ONLY when the window is being resized by dragging lower right (or upper right or lower left) corner
so that one dimension (e.g. width) is increasing and the other dimension (is decreasing).
In that case the newly emerging areas are always filled in with white color which can be observed as terrible flickering.

Curiously the flickering does not happen:
- when you resize the window so that BOTH width and height are increasing
- when you resize the window by dragging the upper left corner

This is not a problem when you have light theme (then window background is probably white anyway).
But this is a big issue when you have dark theme, in which case it is superugly.

Notes:
1) there seems to be the same problem in QtWidgets and QtQuick applications,
   I have not found any Qt application which would behave correctly
2) This is not a problem of Windows OS. Non-Qt applications which I have tested
   seem to behave correctly, i.e. no flickering.
*/

#include <QApplication>
#include <QWidget>
#include <QPainter>
#include <QThread>

class Widget : public QWidget
{
public:
    Widget()
    {
        /*
        The following code was used for experiments. But nothing worked, I could not get rid of flickering.
        The documentation says:
        autoFillBackground : bool
        This property holds whether the widget background is filled automatically
        If enabled, this property will cause Qt to fill the background of the widget before invoking the paint event.
        The color used is defined by the QPalette::Window color role from the widget's palette.
        */
        //setAttribute(Qt::WA_OpaquePaintEvent, true);
        //setAttribute(Qt::WA_NoSystemBackground, true);
        //setAutoFillBackground(false);
        //QPalette p = palette();
        //p.setColor(QPalette::Window, Qt::blue);
        //setPalette(p);
    }

    void paintEvent(QPaintEvent *) override
    {
        QPainter p(this);
        p.fillRect(0, 0, width(), height(), Qt::blue);
        QThread::msleep(50); // just to simulate slower painting
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

UPDATE2:我懷疑問題可能出在QWindowsWindow::handleGeometryChange()請參閱https://code.woboq.org/qt5/qtbase/src/plugins/platforms/windows/qwindowswindow.cpp.ZFC35FDC70D5FC69D269883A822C7A雖然我不知道如何修復它。 我將此問題報告為錯誤https://bugreports.qt.io/browse/QTBUG-89688

UPDATE3:從 Qt 6.1 開始,該錯誤似乎已修復。 做得好。

此錯誤已在 Qt 6.1 中修復。 據我在我的項目中測試它,白色區域的閃爍消失了。

更新:這僅適用於 QtWidget 應用程序。 對於 QtQuick/QML,從 Qt 6.3 開始仍然有很多閃爍。 參見例如https://bugreports.qt.io/browse/QTBUG-103201

暫無
暫無

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

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