Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Why not use native widgets?
QtWS25 Last Chance

Why not use native widgets?

Scheduled Pinned Locked Moved Unsolved General and Desktop
36 Posts 5 Posters 5.5k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B brainchild
    29 Nov 2022, 21:00

    @Chris-Kawa

    What you are describing is Qt interpreting low-level input as high-level state changes for the widget, then expressing those changes into stateless calls of the widget rendering engine. The result is that Qt is the gatekeeper of which real effects (e.g. left mouse button pressed and held longer than 300 ms) represent which high-level state changes (e.g. the button entering a pressed state from unpressed). The button cannot express itself, through a life of its own, by hearing the mouse events and deciding when to explain that it has entered into a pressed state and that specific regions within itself need to be refreshed. Augmentation or refinement within the platform toolkit is not possible. Meanwhile, repainting occurs only when requested by Qt, and only from scratch. It is not helpful that the repaint call may constrain a region for the widget to determine which regions it determines have change based on its own analysis of internal internal state.

    C Offline
    C Offline
    Chris Kawa
    Lifetime Qt Champion
    wrote on 29 Nov 2022, 21:25 last edited by
    #22

    @brainchild I don't really see where you get those ideas from. I'm kinda lost what are we discussing here. Are you asking something or suggesting? I'm not sure what you want me to do.

    As for how it works. An example of what happens when you click a button:

    • User presses a mouse button and OS sends a message WM_LBUTTONDOWN with global mouse position.
    • Qt translates that into QEvent::MouseButtonPress, looks up widget at given coords and posts a QMouseEvent to that widget
    • Widget executes a mousePressEvent(QMouseEvent*) handler. In it a pressed state is determined and stored.
    • Since the state changed widget requests an update(). This marks it dirty and schedules a repaint.
    • Widget executes a paintEvent(QPaintEvent*) handler in which it calls the platform plugin abstraction to paint its state. If it's animated or anything like that it can start the animation, timers, schedule further updates or whatever it needs.
    • If some further updates were scheduled widget executes further paintEvent(QPaintEvent*) handlers.
    • At some point (3s or 300ms later, doesn't matter) user releases the button and OS sends WM_LBUTTONUP
    • Qt translates that into QEvent::MouseButtonRelease and posts another QMouseEvent to the widget.
    • Widget executes a mouseReleaseEvent(QMouseEvent*) handler. In it the pressed state is terminated and new state stored.
    • Since both press and release occurred widget emits a clicked() signal.
    • Since the state changed widget requests an update(). This marks it dirty and schedules a repaint.
    • Widget executes a paintEvent(QPaintEvent*) handler in which it calls the platform plugin abstraction to paint its new state. Other housekeeping can be performed here e.g terminating animations.
    • and so on...

    Maybe you should just read the Qt's code if you're interested in such details?

    B 1 Reply Last reply 29 Nov 2022, 21:37
    1
    • C Chris Kawa
      29 Nov 2022, 21:25

      @brainchild I don't really see where you get those ideas from. I'm kinda lost what are we discussing here. Are you asking something or suggesting? I'm not sure what you want me to do.

      As for how it works. An example of what happens when you click a button:

      • User presses a mouse button and OS sends a message WM_LBUTTONDOWN with global mouse position.
      • Qt translates that into QEvent::MouseButtonPress, looks up widget at given coords and posts a QMouseEvent to that widget
      • Widget executes a mousePressEvent(QMouseEvent*) handler. In it a pressed state is determined and stored.
      • Since the state changed widget requests an update(). This marks it dirty and schedules a repaint.
      • Widget executes a paintEvent(QPaintEvent*) handler in which it calls the platform plugin abstraction to paint its state. If it's animated or anything like that it can start the animation, timers, schedule further updates or whatever it needs.
      • If some further updates were scheduled widget executes further paintEvent(QPaintEvent*) handlers.
      • At some point (3s or 300ms later, doesn't matter) user releases the button and OS sends WM_LBUTTONUP
      • Qt translates that into QEvent::MouseButtonRelease and posts another QMouseEvent to the widget.
      • Widget executes a mouseReleaseEvent(QMouseEvent*) handler. In it the pressed state is terminated and new state stored.
      • Since both press and release occurred widget emits a clicked() signal.
      • Since the state changed widget requests an update(). This marks it dirty and schedules a repaint.
      • Widget executes a paintEvent(QPaintEvent*) handler in which it calls the platform plugin abstraction to paint its new state. Other housekeeping can be performed here e.g terminating animations.
      • and so on...

      Maybe you should just read the Qt's code if you're interested in such details?

      B Offline
      B Offline
      brainchild
      wrote on 29 Nov 2022, 21:37 last edited by brainchild
      #23

      @Chris-Kawa

      Let's make it simple, even if it means being silly.

      Suppose the next version of the platform's widget toolkit is changed such that every button will change its text color every 10 seconds, automatically, following a round-robin selection of six colors. If a button is allocated as a system resource, then it may implement this behavior by setting a timer for 10 seconds, and when receiving a callback, change its internal state for the new color, and then notify that the region containing its text is has become invalid. Such behavior cannot occur, from what I understand, through Qt, because Qt does not recognize the particular internal behavior as a feature of the widget. The widget state and events are only that which Qt keeps and follows, based on its generic, system-agnostic understanding of a button, which does not include the timer, repainting, or color selection, which a system resource could manage itself.

      Surely there are non-silly, and quite real, examples of such limitations.

      Has my presentation exposed some misunderstanding?

      C 1 Reply Last reply 29 Nov 2022, 21:58
      0
      • B brainchild
        29 Nov 2022, 21:37

        @Chris-Kawa

        Let's make it simple, even if it means being silly.

        Suppose the next version of the platform's widget toolkit is changed such that every button will change its text color every 10 seconds, automatically, following a round-robin selection of six colors. If a button is allocated as a system resource, then it may implement this behavior by setting a timer for 10 seconds, and when receiving a callback, change its internal state for the new color, and then notify that the region containing its text is has become invalid. Such behavior cannot occur, from what I understand, through Qt, because Qt does not recognize the particular internal behavior as a feature of the widget. The widget state and events are only that which Qt keeps and follows, based on its generic, system-agnostic understanding of a button, which does not include the timer, repainting, or color selection, which a system resource could manage itself.

        Surely there are non-silly, and quite real, examples of such limitations.

        Has my presentation exposed some misunderstanding?

        C Offline
        C Offline
        Chris Kawa
        Lifetime Qt Champion
        wrote on 29 Nov 2022, 21:58 last edited by Chris Kawa
        #24

        @brainchild Yes, it's a limitation, but not very important in practice. The situation you describe doesn't happen very often. A lot of windowing frameworks work like that, not just Qt, and OS manufacturers don't have any real incentive to break most applications look with new releases. They rather go out of their way not to do that, even when they change the look and feel. Windows APIs and behavior for example haven't changed since Windows XP (over 20 years). The look of the controls changed, some colors maybe, but not the fundamental mechanic. If it happens Qt can just update its platform plugin. The current one didn't need updating for a long time (it's still called WindowsVistaStyle if I'm not mistaken).

        If you don't like that limitation anyway, you can provide your own platform plugin that will instantiate a bunch of system objects and get rid of that limitation that way. It's a plugin, so it's flexible. Can be updated independently or entirely replaced.

        B 1 Reply Last reply 29 Nov 2022, 22:05
        0
        • C Chris Kawa
          29 Nov 2022, 21:58

          @brainchild Yes, it's a limitation, but not very important in practice. The situation you describe doesn't happen very often. A lot of windowing frameworks work like that, not just Qt, and OS manufacturers don't have any real incentive to break most applications look with new releases. They rather go out of their way not to do that, even when they change the look and feel. Windows APIs and behavior for example haven't changed since Windows XP (over 20 years). The look of the controls changed, some colors maybe, but not the fundamental mechanic. If it happens Qt can just update its platform plugin. The current one didn't need updating for a long time (it's still called WindowsVistaStyle if I'm not mistaken).

          If you don't like that limitation anyway, you can provide your own platform plugin that will instantiate a bunch of system objects and get rid of that limitation that way. It's a plugin, so it's flexible. Can be updated independently or entirely replaced.

          B Offline
          B Offline
          brainchild
          wrote on 29 Nov 2022, 22:05 last edited by brainchild
          #25

          @Chris-Kawa

          I am wondering whether the more serious limitation relates to lack of optimization for repainted regions, as a stateful resource would be able to compute the bounds of a physical region having become invalid, based on changes in conceptual state, and its own understanding of how such changes relate to its own paint process.

          C 1 Reply Last reply 29 Nov 2022, 22:20
          0
          • B brainchild
            29 Nov 2022, 22:05

            @Chris-Kawa

            I am wondering whether the more serious limitation relates to lack of optimization for repainted regions, as a stateful resource would be able to compute the bounds of a physical region having become invalid, based on changes in conceptual state, and its own understanding of how such changes relate to its own paint process.

            C Offline
            C Offline
            Chris Kawa
            Lifetime Qt Champion
            wrote on 29 Nov 2022, 22:20 last edited by Chris Kawa
            #26

            @brainchild I think you overestimate that optimization potential.

            Simple controls do simple things e.g. a panel will usually just fill it with a color or a gradient. If control has text, like buttons or menu item, it's ballpark the same work to calculate proper text positioning, kerning etc. as simply drawing the whole thing clipped to the region.

            If you think about it the set of basic UI controls is not that large and they are all pretty basic. More complicated ones like lists, tables etc. are just composition of the basic ones. If you have a very complicated control, like a chart or 3D scene, there's no native controls for that anyway, so all painting is custom one way or another. If you have highly animated UI toolkit it probably draws using an accelerated API like OpenGL or Vulkan, and the cost of figuring out on the CPU sub-changes needed is often a pessimization, as the GPU can draw them faster than the CPU can feed it anyway, so it's actually more performant to just draw it all.

            I don't think many toolkits do the sub-control optimizations that you think of.

            B 1 Reply Last reply 29 Nov 2022, 22:36
            0
            • C Chris Kawa
              29 Nov 2022, 22:20

              @brainchild I think you overestimate that optimization potential.

              Simple controls do simple things e.g. a panel will usually just fill it with a color or a gradient. If control has text, like buttons or menu item, it's ballpark the same work to calculate proper text positioning, kerning etc. as simply drawing the whole thing clipped to the region.

              If you think about it the set of basic UI controls is not that large and they are all pretty basic. More complicated ones like lists, tables etc. are just composition of the basic ones. If you have a very complicated control, like a chart or 3D scene, there's no native controls for that anyway, so all painting is custom one way or another. If you have highly animated UI toolkit it probably draws using an accelerated API like OpenGL or Vulkan, and the cost of figuring out on the CPU sub-changes needed is often a pessimization, as the GPU can draw them faster than the CPU can feed it anyway, so it's actually more performant to just draw it all.

              I don't think many toolkits do the sub-control optimizations that you think of.

              B Offline
              B Offline
              brainchild
              wrote on 29 Nov 2022, 22:36 last edited by brainchild
              #27

              @Chris-Kawa said in Why not use native widgets?:

              I don't think many toolkits do the sub-control optimizations that you think of.

              The design that has been familiar to me is that container widgets manage the events of their children, such that it would be important for a container to propagate up the chain the specific bounds of some region that has become invalid, as would correspond to some non-container descendant, to avoid repainting the entire container including descendants. It seems that Qt uses a different model of event propagation, with a widget hierarchy being applied more narrowly to resolve concerns such as position and z-order of paint composition, or recipient of mouse and key events.

              1 Reply Last reply
              0
              • C Online
                C Online
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on 30 Nov 2022, 06:14 last edited by
                #28

                Qt does exactly the same - how should it work otherwise?
                The code of Qt is open-source - take a look at the event handling or make a breakpoint in your paintEvent() to see where it comes from and you will see the event propagation exactly like it's done in other frameworks.
                Also Qt is using native drawing methods to draw it's widgets - see the windows style plugin on how it works.

                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                Visit the Qt Academy at https://academy.qt.io/catalog

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  SimonSchroeder
                  wrote on 30 Nov 2022, 08:51 last edited by
                  #29

                  @brainchild It seems like you think the native window calls are more performant that Qt's. As has been explained excessively, Qt provides the faster approach by not creating individual OS objects. So, Qt is faster than the native API. You can use a more modern API for Windows for comparable native performance (I don't know any of those). However, these are usually short lived and you need to rewrite your application every couple of years. Qt brings a lot more stability which is a good thing for commercial applications. And as told repeatedly: Qt uses the OS's functionality to draw buttons, labels, combo boxes, etc. An update to the looks by the OS will then also update Qt's look. Rarely does Qt need to change to conform to a new look.

                  Concerning event handling: Qt translates events one-to-one from the native events to Qt events. No information is lost. There is nothing (nothing I know of) that the native API can do that Qt can't do. I think there are a few special things on macOS. However, there is always the possibility to also receive the native events if you want to. And the optimization of draw calls you have been talking about is also done by Qt. Qt will only request a redraw for the widgets within the QRect, just as the OS would do by itself. And then finally only the part of the native window will be changed with the image from the back buffer. The only "performance penalty" is the use of a back buffer instead directly drawing onto the window. This, however, is necessary for a good user experience anyway. So, the best implementation cannot get any faster than this.

                  Finally, the reason for using Qt is not to write a Windows program. If you want to do that, just use the native API. The reason for using Qt is writing portable code. And it is still the best tool for writing portable desktop applications. I even think it has the superior API compared to Windows. Concerning the looks of your application: We spend a great deal to have more modern look for our professional application. This means using stylesheets. Using native APIs we would not be able to do that. We specifically switched to Qt to update to a more modern look. Also, we tried to have a similar look on all platforms. For us it is a hindrance that Qt uses the native APIs for drawing controls. I would prefer to not use stylesheets but change colors solely based on the palette. This does not work because Qt uses the native APIs. I would use the Fusion style, but that is honestly too playful for a professional application. Furthermore, some stylesheet changes will break a lot. For example, if you change any part of the look of a QPushButton, layouts will compute a different width for the button. Suddenly, your 'Ok' and 'Cancel' buttons at the bottom of the dialog will have different widths instead of being the same width as expected. So, I vote for Qt to drop the native drawing calls and fake the whole look so I can use palettes instead of stylesheets and not break any layouting while changing the looks.

                  B 1 Reply Last reply 30 Nov 2022, 09:34
                  1
                  • S SimonSchroeder
                    30 Nov 2022, 08:51

                    @brainchild It seems like you think the native window calls are more performant that Qt's. As has been explained excessively, Qt provides the faster approach by not creating individual OS objects. So, Qt is faster than the native API. You can use a more modern API for Windows for comparable native performance (I don't know any of those). However, these are usually short lived and you need to rewrite your application every couple of years. Qt brings a lot more stability which is a good thing for commercial applications. And as told repeatedly: Qt uses the OS's functionality to draw buttons, labels, combo boxes, etc. An update to the looks by the OS will then also update Qt's look. Rarely does Qt need to change to conform to a new look.

                    Concerning event handling: Qt translates events one-to-one from the native events to Qt events. No information is lost. There is nothing (nothing I know of) that the native API can do that Qt can't do. I think there are a few special things on macOS. However, there is always the possibility to also receive the native events if you want to. And the optimization of draw calls you have been talking about is also done by Qt. Qt will only request a redraw for the widgets within the QRect, just as the OS would do by itself. And then finally only the part of the native window will be changed with the image from the back buffer. The only "performance penalty" is the use of a back buffer instead directly drawing onto the window. This, however, is necessary for a good user experience anyway. So, the best implementation cannot get any faster than this.

                    Finally, the reason for using Qt is not to write a Windows program. If you want to do that, just use the native API. The reason for using Qt is writing portable code. And it is still the best tool for writing portable desktop applications. I even think it has the superior API compared to Windows. Concerning the looks of your application: We spend a great deal to have more modern look for our professional application. This means using stylesheets. Using native APIs we would not be able to do that. We specifically switched to Qt to update to a more modern look. Also, we tried to have a similar look on all platforms. For us it is a hindrance that Qt uses the native APIs for drawing controls. I would prefer to not use stylesheets but change colors solely based on the palette. This does not work because Qt uses the native APIs. I would use the Fusion style, but that is honestly too playful for a professional application. Furthermore, some stylesheet changes will break a lot. For example, if you change any part of the look of a QPushButton, layouts will compute a different width for the button. Suddenly, your 'Ok' and 'Cancel' buttons at the bottom of the dialog will have different widths instead of being the same width as expected. So, I vote for Qt to drop the native drawing calls and fake the whole look so I can use palettes instead of stylesheets and not break any layouting while changing the looks.

                    B Offline
                    B Offline
                    brainchild
                    wrote on 30 Nov 2022, 09:34 last edited by brainchild
                    #30

                    @SimonSchroeder

                    Yes, I have begun to understand better than before. I think the explanation that feels clear to me is that Qt uses native calls to draw the primitive elements with a native appearance, but provides through its own libraries many of the higher-level fundamentals, such as layout and positioning, invalidation of window regions, translation between primitive and high-level events, and so on. Thus, it employs a hybrid model, abstracting most features that port well into its own libraries, but reserving native calls for the lowest-level operations, including painting primitive widgets.

                    The topic is one that has seemed to be a source of much confusion, not just for me. It might be helpful if the Qt team would include some explanation in the main documentation, or perhaps a post in some blog that is discoverable through a web search.

                    C 1 Reply Last reply 30 Nov 2022, 10:10
                    0
                    • B brainchild
                      30 Nov 2022, 09:34

                      @SimonSchroeder

                      Yes, I have begun to understand better than before. I think the explanation that feels clear to me is that Qt uses native calls to draw the primitive elements with a native appearance, but provides through its own libraries many of the higher-level fundamentals, such as layout and positioning, invalidation of window regions, translation between primitive and high-level events, and so on. Thus, it employs a hybrid model, abstracting most features that port well into its own libraries, but reserving native calls for the lowest-level operations, including painting primitive widgets.

                      The topic is one that has seemed to be a source of much confusion, not just for me. It might be helpful if the Qt team would include some explanation in the main documentation, or perhaps a post in some blog that is discoverable through a web search.

                      C Online
                      C Online
                      Christian Ehrlicher
                      Lifetime Qt Champion
                      wrote on 30 Nov 2022, 10:10 last edited by
                      #31

                      @brainchild said in Why not use native widgets?:

                      It might be helpful if the Qt team would include some explanation in the main documentation, or perhaps a post in some blog that is discoverable through a web search.

                      Why? What exactly do you need? That Qt does it's own painting? Is documented. That Qt abstracts the OS? That's the main purpose for this library.

                      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                      Visit the Qt Academy at https://academy.qt.io/catalog

                      B 1 Reply Last reply 30 Nov 2022, 10:24
                      1
                      • C Christian Ehrlicher
                        30 Nov 2022, 10:10

                        @brainchild said in Why not use native widgets?:

                        It might be helpful if the Qt team would include some explanation in the main documentation, or perhaps a post in some blog that is discoverable through a web search.

                        Why? What exactly do you need? That Qt does it's own painting? Is documented. That Qt abstracts the OS? That's the main purpose for this library.

                        B Offline
                        B Offline
                        brainchild
                        wrote on 30 Nov 2022, 10:24 last edited by
                        #32

                        @Christian-Ehrlicher said in Why not use native widgets?:

                        @brainchild said in Why not use native widgets?:

                        Why? What exactly do you need? That Qt does it's own painting? Is documented. That Qt abstracts the OS? That's the main purpose for this library.

                        Perhaps everyone already understands except for me, but it's not my impression reading comments and questions.

                        1 Reply Last reply
                        0
                        • C Online
                          C Online
                          Christian Ehrlicher
                          Lifetime Qt Champion
                          wrote on 30 Nov 2022, 10:34 last edited by
                          #33

                          Read e.g. https://doc.qt.io/qt-6/topics-graphics.html

                          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                          Visit the Qt Academy at https://academy.qt.io/catalog

                          B 1 Reply Last reply 30 Nov 2022, 12:03
                          0
                          • C Christian Ehrlicher
                            30 Nov 2022, 10:34

                            Read e.g. https://doc.qt.io/qt-6/topics-graphics.html

                            B Offline
                            B Offline
                            brainchild
                            wrote on 30 Nov 2022, 12:03 last edited by
                            #34

                            @Christian-Ehrlicher said in Why not use native widgets?:

                            Read e.g. https://doc.qt.io/qt-6/topics-graphics.html

                            I have not found an explanation as the one discussed here in the referenced documentation, but I will review it more carefully when able.

                            W 1 Reply Last reply 30 Nov 2022, 20:51
                            0
                            • B brainchild
                              30 Nov 2022, 12:03

                              @Christian-Ehrlicher said in Why not use native widgets?:

                              Read e.g. https://doc.qt.io/qt-6/topics-graphics.html

                              I have not found an explanation as the one discussed here in the referenced documentation, but I will review it more carefully when able.

                              W Offline
                              W Offline
                              wrosecrans
                              wrote on 30 Nov 2022, 20:51 last edited by
                              #35

                              @brainchild

                              The sorts of stuff you are asking about are pretty much just obscure implementation details. Most people don't make an assumption that 1:1 platform widgets to QWidgets would be a major performance improvement, so it wouldn't occur to folks that the opposite needs to have some sort of explanation or justification. It literally has zero effect on day to day usage of the Qt public API. And for most people who care about digging into the low level platform specific guts, having a caching layer in Qt makes sense by the time they get anywhere near a place where it matters.

                              B 1 Reply Last reply 30 Nov 2022, 21:36
                              1
                              • W wrosecrans
                                30 Nov 2022, 20:51

                                @brainchild

                                The sorts of stuff you are asking about are pretty much just obscure implementation details. Most people don't make an assumption that 1:1 platform widgets to QWidgets would be a major performance improvement, so it wouldn't occur to folks that the opposite needs to have some sort of explanation or justification. It literally has zero effect on day to day usage of the Qt public API. And for most people who care about digging into the low level platform specific guts, having a caching layer in Qt makes sense by the time they get anywhere near a place where it matters.

                                B Offline
                                B Offline
                                brainchild
                                wrote on 30 Nov 2022, 21:36 last edited by brainchild
                                #36

                                @wrosecrans said in Why not use native widgets?:

                                The sorts of stuff you are asking about are pretty much just obscure implementation details.

                                Yes, but questions about the issues are asked frequently, with an abundance of misunderstanding or misinformation given in response. As long as the questions are asked, it seems better that answers are available and accurate, especially against an alternative of being available but inaccurate.

                                1 Reply Last reply
                                0

                                31/36

                                30 Nov 2022, 10:10

                                • Login

                                • Login or register to search.
                                31 out of 36
                                • First post
                                  31/36
                                  Last post
                                0
                                • Categories
                                • Recent
                                • Tags
                                • Popular
                                • Users
                                • Groups
                                • Search
                                • Get Qt Extensions
                                • Unsolved