简体   繁体   中英

flickering white areas when resizing Qt window

I am observing a strange behavior when resizing QWindow . When I resize the window so that both width and height are increasing or decreasing, then the window does not flicker with white background. But when I increase width while decreasing height (or vice versa) the window flickers and temporarily fill the new are with white color. This is a very annoying effect especially when I have a dark theme in my application and I resize the window.

To experiment with this I used "rasterwindow" example bundled in Qt SDK. This does not use QtWidgets so I used this example so that I rule out the effect is caused by widgets. I added QThread::msleep(100); to RasterWindow::render(QPainter *) function to simulate a very slow rendering. Then I tried to resize the window. I can observe this only on Windows but not on Linux or Mac. See the attached GIF.

My questions:

  1. Any idea what is causing the problem? Why only on Windows?
  2. Why it cannot be observed when increasing both width and height? And why is it observed when decreasing one dimension and increasing the other?
  3. How to get rid of it?
  4. If I am not able to get rid of it completely, can I fill the new area with other color than white (so that it is not so much annoying in dark theme)?

在此处输入图像描述

UPDATE: I created minimalistic example here

/*
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: My suspicion is that the problem might be in QWindowsWindow::handleGeometryChange() see https://code.woboq.org/qt5/qtbase/src/plugins/platforms/windows/qwindowswindow.cpp.html though I do not know how to fix it. I reported this issue as a bug https://bugreports.qt.io/browse/QTBUG-89688

UPDATE3: The bug seems to be fixed as of Qt 6.1. Well done.

This bug has been fixed in Qt 6.1. As far as I tested it in my projects flickering of the white areas is gone.

UPDATE: This holds only for QtWidget applications. For QtQuick/QML there is still a lots of flicker as of Qt 6.3. See eg https://bugreports.qt.io/browse/QTBUG-103201

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM