Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Can someone help me undertand why this white background never really goes away?



  • Hi,

    I am new here, And I am still learning QT so please take it easy on me :)

    I downloaded the QT Creator and I created a simple app. This is basically it.

    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
    
        QPalette pal = w.palette();
        pal.setColor(QPalette::Window, QColor(Qt::black));
        w.setPalette(pal);
    
        w.show();
        return a.exec();
    }
    

    Now when I run it and try to resize the window, This happens.
    Click To Watch Video

    Basically, When the app first starts, The default white background is first shown for a split second and THEN the color changes to what I set it to at startup (black).
    Also what's more important, Is when I try to resize the window or move it from one screen to the other it shows the original white background as it repaints over it with black.

    Is this normal? Any idea how to fix or avoid this?

    I am on windows 10 64bit
    Qt Creator 4.12.1
    Based on Qt 5.14.2 (MSVC 2017, 32 bit)
    Screen resolution is 3840x2160

    Thanks in advance and forgive me if it's a noob question because I have searched google for an answer and couldn't find any that helped.



  • @SqueakyBed Thank your for asking this question! I've also seen this flickering sometimes, in fact it's an age-old Windows "feature".

    This morning I had some good coffee so I finally got the energy to research this problem. As usual, Raymond Chen gives you a helping hand: here's his writeup of this called "The white flash" (from 2004!) https://devblogs.microsoft.com/oldnewthing/?p=40943

    Insert one line (and #include "windows.h") and begone the white flicker (at least on my PC), here's your glorious program modified:

    #include <windows.h>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
    
        QPalette pal = w.palette();
        pal.setColor(QPalette::Window, QColor(Qt::black));
        w.setPalette(pal);
    
        SetClassLongPtr((HWND) w.winId(),GCLP_HBRBACKGROUND,(LONG_PTR) CreateSolidBrush(RGB(0,0,0)));
        
        w.show();
        return a.exec();
    }
    

    Note: RGB(0,0,0) is the ancient Win32 way of specifying the black color.

    Edit: sorry, forgot to mention, you need to include this line in your .pro file for the build to be ok:

    LIBS += -luser32 -lgdi32
    

    and changed to #include <windows.h> thanks @JonB



  • @SqueakyBed
    This does not answer your question about using a palette, but a lot of people would accomplish what you are doing via w.setStyleSheet("background-color: black;"). I don't know whether that might not exhibit your issue, and you might like to change to this way?



  • @JonB said in Can someone help me undertand why this white background never really goes away?:

    w.setStyleSheet("background-color: black;")

    I did try that, But unfortunately it made no difference.

    Thanks.



  • @SqueakyBed
    Again, I'm sorry this is not the answer you are looking for, but....

    ...When I do this I do not get the "white flashing" I see in your video. (I don't know whether that "flash" might be from a window briefly showing a potential scrollbar, not that it helps you much. You could try stretching at top left instead of bottom right and see where the flashing occurs for that?). I'm wondering whether this might be an artefact of your graphics card, are you able to test your behaviour on another machine?



  • It seems like it only happens when I drag the right or the bottom edges.

    Click To Watch Video

    I am running a 1080ti btw and it's working just fine no problems whatsoever.

    @JonB



  • @SqueakyBed

    I'm wondering whether this might be an artefact of your graphics card, are you able to test your behaviour on another machine?



  • @SqueakyBed Thank your for asking this question! I've also seen this flickering sometimes, in fact it's an age-old Windows "feature".

    This morning I had some good coffee so I finally got the energy to research this problem. As usual, Raymond Chen gives you a helping hand: here's his writeup of this called "The white flash" (from 2004!) https://devblogs.microsoft.com/oldnewthing/?p=40943

    Insert one line (and #include "windows.h") and begone the white flicker (at least on my PC), here's your glorious program modified:

    #include <windows.h>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
    
        QPalette pal = w.palette();
        pal.setColor(QPalette::Window, QColor(Qt::black));
        w.setPalette(pal);
    
        SetClassLongPtr((HWND) w.winId(),GCLP_HBRBACKGROUND,(LONG_PTR) CreateSolidBrush(RGB(0,0,0)));
        
        w.show();
        return a.exec();
    }
    

    Note: RGB(0,0,0) is the ancient Win32 way of specifying the black color.

    Edit: sorry, forgot to mention, you need to include this line in your .pro file for the build to be ok:

    LIBS += -luser32 -lgdi32
    

    and changed to #include <windows.h> thanks @JonB



  • @hskoglund
    Good answer! But should your #include "windows.h" be #include <windows.h> (it's in a "system" directory) to be correct?



  • @JonB Both works, but yeah, <windows.h> looks better, changed it...



  • @hskoglund The window still flashes white for a moment when the app starts but it fixed the flashing while resizing the window problem.

    Thanks guys :)



  • @hskoglund That is a very nice solution. Thank you very much.

    There is something else you might want to try. The reason for the flickering could be that first Windows draws into the new area and only after that the paint event of your widget gets called. There might be a little delay between the two. QWidgets have a property autoFillBackground which by default is set to false. The documentation says this:

    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.

    Perhaps this helps without resorting to Windows-specific function calls.

    I am not sure if this solves the problem. Let me know if it helps.



  • Good point about autoFillBackground (also I see in the docs there's another property Qt::WA_OpaquePaintEvent, setting that might help as well).
    And as you say, it's always better to avoid non-portable, Windows-specific API calls.

    Finally, there's a potential problem with that SetClassLongPtr ... call from yesterday: if you create additional widgets with another background than the original black, the flicker will rear its ugly head again. Consider this version of yesterday's main.cpp:

    #include <windows.h>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
    
        QPalette pal = w.palette();
        pal.setColor(QPalette::Window, QColor(255,255,0));
        w.setPalette(pal);
    
        SetClassLongPtr((HWND) w.winId(),GCLP_HBRBACKGROUND,(LONG_PTR) CreateSolidBrush(RGB(255,255,0)));
        w.show();
    
        QWidget mrWhite;
        mrWhite.setWindowTitle("Mr.White");
        mrWhite.show();
    
        return a.exec();
    }
    

    The 2nd widget will also be affected by that SetClassLongPtr... call.
    To see this effect more easily, I've set the original/first window's background to yellow. Now if you resize/move Mr.White around, you'll see a yellow flicker. (This is not a problem if all your windows share the same palette.)


Log in to reply