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

attributes in qt - what means?



  • Hello,

    I have a problem with understand what a few attributes to widgets means. The first one is:

    Qt::WidgetAttribute::WA_NativeWindow
    

    What is difference between that attribute and non-native-window? Is there any difference in graphic?

    For example: I set this attribute in my mainWindow. So what I get?


  • Moderators

    Here is how QWidget docs explain it: https://doc.qt.io/qt-5/qwidget.html#native-widgets-vs-alien-widgets

    It's not much info, though.


  • Moderators

    Platforms provide a native way to show a window and give you some sort of handle to it.

    For example on Windows you can use CreateWindowEx function that returns a HWND and each "control" is a window e.g a button, panel, checkbox, all are visible to the Os as windows and have a unique HWND. It's similar on other platforms, except they use different handle types.

    Qt abstracts this away. By default it only creates one top level window and then draws all the widgets inside as on a canvas. To Qt these are distinct objects but to the OS there's only one window with some custom paint event. This is done for several reasons, mostly to do with performance and resolving flicker issues, but it also makes it easier to do multiplatforming, as everything inside the window is handled the same on every platform, only the top level window has a platform specific handle.

    By using that flag you're forcing Qt to create a native window for a widget i.e. if you set it on a button it gets its own window (in the OS api sense, not visually) and handle. There' usually no reason to use it and it can degrade performance of your app. It's needed in specific scenarios, for example when interacting with 3rd party APIs that require native window handles.

    For example: I set this attribute in my mainWindow. So what I get?

    Top level windows are always native, so if your mainWindow is the top level window of your app this does nothing, as the window already is a native window.



  • @Chris-Kawa Perfect. Thank you! :)

    @sierdzio Thank you too :)

    Next ( the last two ):

    1. Qt::WidgetAttribute::WA_NoSystemBackground

    2. Qt::WA_PaintOnScreen

    @Chris-Kawa Can you explain this two too? :)

    EDIT:
    And small question to Qt::WidgetAttribute::WA_NativeWindow:

    I check it:

    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        but = new QPushButton(this);
    
        connect(but, SIGNAL(clicked()), this, SLOT(clickedSlot()));
        but->setGeometry(0,0,19,81);
    }
    
    void MainWindow::clickedSlot()
    {
        RECT rect;
        if(GetWindowRect((HWND)but->winId(), &rect))
        {
          int width = rect.right - rect.left;
          int height = rect.bottom - rect.top;
          qInfo()<<width<<height;
        }
    }
    

    And I see the correct size. But you said that only mainWindow is a native window. I don't set that attribute in "but". So why this button has HWND?


  • Moderators

    All these flags are described here: Qt::WidgetAttribute.

    In short with WA_NoSystemBackground set widget will not have its background filled with background color just before paint event. This can save a bit of performance if you paint entire widget yourself anyway or cover it entirely with other widgets. The docs say the window will be see through until you paint on it, but that's really window manager dependent. It's no longer true in Windows 10 for example. You'll just get default (black) background from the DWM.

    WA_PaintOnScreen is a Linux thing and I'm not well versed in that, but from what I understand it tries to bypass any composition and draw directly on "desktop". This was used to possible on Windows too, but I wouldn't be surprised if modern window managers wouldn't let you do that.

    So why this button has HWND?

    Because you gave it one :) Calling winId() on a widget makes it a native window and gives it that native attribute. This is also documented. If you want to test if a widget is native check its attributes instead of calling winId().


Log in to reply