简体   繁体   English

调整大小时闪烁的白色区域 Qt window

[英]flickering white areas when resizing Qt window

I am observing a strange behavior when resizing QWindow .我在调整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.当我调整 window 的大小以使宽度和高度都增加或减少时,window 不会在白色背景下闪烁。 But when I increase width while decreasing height (or vice versa) the window flickers and temporarily fill the new are with white color.但是当我在减小高度的同时增加宽度(反之亦然)时,window 会闪烁并暂时用白色填充新区域。 This is a very annoying effect especially when I have a dark theme in my application and I resize the window.这是一个非常烦人的效果,尤其是当我的应用程序中有一个深色主题并且我调整了 window 的大小时。

To experiment with this I used "rasterwindow" example bundled in Qt SDK.为了对此进行试验,我使用了捆绑在 Qt SDK 中的“rasterwindow”示例。 This does not use QtWidgets so I used this example so that I rule out the effect is caused by widgets.这不使用QtWidgets ,所以我使用了这个示例,以便排除效果是由小部件引起的。 I added QThread::msleep(100);我添加了QThread::msleep(100); to RasterWindow::render(QPainter *) function to simulate a very slow rendering.RasterWindow::render(QPainter *) function 来模拟非常慢的渲染。 Then I tried to resize the window.然后我尝试调整 window 的大小。 I can observe this only on Windows but not on Linux or Mac.我只能在 Windows 上观察到这一点,但不能在 Linux 或 Mac 上观察到。 See the attached GIF.请参阅随附的 GIF。

My questions:我的问题:

  1. Any idea what is causing the problem?知道是什么导致了问题吗? Why only on Windows?为什么只在 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. UPDATE2:我怀疑问题可能出在QWindowsWindow::handleGeometryChange()请参阅https://code.woboq.org/qt5/qtbase/src/plugins/platforms/windows/qwindowswindow.cpp.ZFC35FDC70D5FC69D269883A822C7A虽然我不知道如何修复它。 I reported this issue as a bug https://bugreports.qt.io/browse/QTBUG-89688我将此问题报告为错误https://bugreports.qt.io/browse/QTBUG-89688

UPDATE3: The bug seems to be fixed as of Qt 6.1. UPDATE3:从 Qt 6.1 开始,该错误似乎已修复。 Well done.做得好。

This bug has been fixed in Qt 6.1.此错误已在 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.更新:这仅适用于 QtWidget 应用程序。 For QtQuick/QML there is still a lots of flicker as of Qt 6.3.对于 QtQuick/QML,从 Qt 6.3 开始仍然有很多闪烁。 See eg https://bugreports.qt.io/browse/QTBUG-103201参见例如https://bugreports.qt.io/browse/QTBUG-103201

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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