[Interest] Guide me through the Qt offerings for GUIs
volker.hilsheimer at qt.io
Thu Apr 22 10:50:44 CEST 2021
> On 21 Apr 2021, at 22:39, Bernhard Lindner <private at bernhard-lindner.de> wrote:
>> Personally, I think the exsting QtQuick element should be scrapped and just focus on QML
>> versions of the existing Widget functionality. I love the QML syntax, hate that it's not
>> just a layer on top of widgets.
> Why this wasn't done from the start is one of the hardest puzzles! I ask myself this
> question every time I read the three letters "QML" :-)
Indeed, it’s an obvious knee-jerk reaction to have when looking at Qt and wondering why there are several UI frameworks.
But there are several reasons why things are as they are. Some of them:
* imperative painting
Paint-event based drawing with a “pen” is not easily reconcilable with how GPUs like to work. Without a persistent scene graph that is uploaded to the GPU, much of the performance you get from a GPU is lost. An animation at 60fps is ideally just a draw call on the GPU with some different transformations, not a completely new upload of a completely reconstructed scene graph for each frame.
Widgets can draw into a framebuffer texture that can be used, and that allows for some integration, but that doesn’t give you great performance.
* integer coordinates and clipping
Widgets work with integer coordinates, which starts to be problematic now that we have high-DPI displays. And widgets clip are clipped to their parent geometry, which was the right choice for those UIs, but is very limiting and requires a lot of complex code to solve conceptually simple problems. Hello macOS focus ring.
Quick items do not clip and are not clipped, which gives a lot more freedom in how shapes are combined and structured.
* declarative vs imperative APIs
Many widget classes don’t have a declarative-friendly API. Plenty of widget properties have side effects on other properties, so the order in which properties are set matters. That doesn’t work well in a declarative world.
Widgets are heavy, often very complex objects. They often come with all bells and whistles. QPushButton always has the data structure to support QPushButton::setMenu, even if probably <1% of buttons out there ever use that feature. That’s ok on desktop machines, it’s not ok on embedded systems.
* complexity and hard to customize
Inheritance and reimplementing are nice concepts on paper and works great if you build your own custom widget from a reasonably abstract base class. But if you have ever tried to subclass e.g. QTreeWidget to modify how certain interactions work, then you know how hard it can be to not break the complex states that the default implementations rely on.
So, making widgets work in a declarative, GPU friendly world where ease of customisation is more important than standard look’n'feel would have required many changes to widgets. Those would have been impossible to make without invalidating or breaking a lot of code out there, and still not given us the UI components we would have needed.
I’m sure there are opportunities to share more code between widgets and quick world esp on the UI framework classes, and with Qt 6 we have taken some steps into that direction. But whether the benefits outweigh the risks and effort requires a case-by-case evaluation.
More information about the Interest