[Interest] Guide me through the Qt offerings for GUIs
Max Paperno
max-l at wdg.us
Fri Apr 30 15:45:39 CEST 2021
On 4/22/2021 4:50 AM, Volker Hilsheimer wrote:
....
>
> * 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 islost. 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.
Why can't "Widgets" be drawn the same way QtQuickItems are drawn? As an
alternative to pen/brush, or direct GL calls. Just like there's a
QtQuickPaintedItem alternative. Essentially it's just another way to
paint a widget (or whatever!)... or am I missing something? What is a
QtQuick Control if not a type of widget?
If you mean batched render of all items in a scene, isn't that a
function of the scene? Or partial redraw of only changed region, or for
that matter only applying a transform if that's all that has changed.
Ideally widgets shouldn't even care what kind of scene they're being
drawn into, but at worst they could be aware and adjust accordingly?
I'm sure I'm oversimplifying and generalizing here. I've read (or tried
to) a number of Qt contributor publications on the matter, trying to
understand, but they typically all start with some bullet points on why
QPainter is "bad" and why it needs to be thrown out, and go from there
(or just dive into how great the new system is) w/out any real
alternative analysis. Many also seem to assume that "mobile" devices (or
"embedding") are the only ones of interest anymore, or at least that's
my impression.
> * 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.
>
Err... Qt Graphics Framework? And GL windows where developer can do
whatever they want? There is (or was) even a note somewhere in the GF
docs about how this may become the future QWidgets underlying framework.
That's all pretty much been abandoned, which is unfortunate because
there's a lot to like in there, including native widgets and nice
layouts. And it is very performant.
Within QWidgets one can already draw in floating point coordinates.
Granted most existing QWidgets don't, but they could. I have a test app
with 10+ animations of various sizes in one window, using QPainter fp
drawing inside QWidgets, running 25+ fps on a little Pi Zero from 2017
pushing a FHD display.
And applications written with either of those "outdated" technologies
actually run fine on phones (Android anyway, never got around to the
other more crippled OS)... it's just that you pretty much need to draw
them yourself right now, or at least heavily customize. I wrote a fully
animated touch-friendly "airplane HUD" type application using Graphics
Framework, 5 years ago now, using all custom-drawn controls, SVG
graphics, and moving maps, pulling live data via radio link from a UAV,
and it ran fine on decently powered phones/tablets of that time. Zero
QML, 99.9% same code for all platforms (not counting build/packaging
scripts!).
So yea, I don't really "buy" this "we had to re-invent the wheel to make
it more efficient." I do get wanting a new shiny carbon fiber wheel.
Just too bad the old but mature wheels get no real love.
> * 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 ina declarative world.
Well this sounds like a major generalization on several levels and I'm
not going into all that, but even if the statement were entirely
correct, this just means another set of widgets which don't care which
order properties are set in... or an abstraction layer over existing
widgets. And yea as mentioned already... what is QtDesigner XML then?
> * weight
>
> Widgets are heavy, often very complex objects. They often come with allbells and whistles. QPushButton always has the data structure to support QPushButton::setMenu, even if probably <1% of buttons out there ever usethat feature. That’s ok on desktop machines, it’s not okon embedded systems.
So QML components are stripped down to the bare minimum functionality
that someone decided was good enough? That does indeed echo some of my
frustration with the relative immaturity of QtQuick controls.
Or is, say, a QtQuick backend C++ button object less complex than using
a QWdiget one? Assuming they both had the same features. I can see how
one could start from scratch and create a simpler version, sure... maybe
optimize some legacy code, sure. But ultimately they'd both have to do
the same logic and drawing steps behind the scenes. I don't see how one
would be "lighter" somehow in the end. If it has fewer features... sure.
The obvious answer to your particular example is to use QAbstractButton
and build up. It already has almost all the same functionality as
QPushButton, w/out the objectionable menu. Hooray for abstraction and
inheritance!
>
>
> * 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.
Maybe it's "complicated" if one is coming from JavaScript of 10 years
ago, but um... no, can't agree at all. Inheritance and re-implementing
is f'ing awesome. It is so ironic to hear you say that because my
biggest frustration with QtQuick Controls 2 was the absolutely inane
"inheritance" model where each theme needs to be re-implemented
separately... with NO access to the underlying C++ objects where
customizing functionality would be, in most cases, far, far easier.
But, sorry, the whole theming system is ridiculously implemented in
regards to QQC2. To me this breaks much of the point of having "themes"
in the first place, which would presumably need to vary from device to
device or based on user preference. In Q[Graphics]Widgets the theme can
be switched much easier. And don't get me started on the irony of not
being able to use CSS in QML.
As for "embedding"... Embedding into what? This term gets thrown around
a lot and is again a huge generalization. One could "embed"
firm/software into pretty much anything these days. It may or may not
have a GPU. Do you mean integrate with an RTOS? That would require some
serious analysis on the part of the implementer IMHO, not just QtC
saying "it works great." I'm not running Qt on my UAVs or radio
controllers, I can tell you that.
And honestly... QTreeWidget as the example? NVM that nothing in QtQuick
even comes close to everything one can do with that, somewhat
bloated/gross, smashup of models and views into one
deceptively-simple-to-start-with object. Or QTreeView for that matter
(which yes I do re-implement quite often, even if it's for just a quick
painter tweak in one virtual method). But there are plenty of better
examples which are absolutely meant to be re-implemented, starting with
the ones that have "Abstract" in their names (something QQC2 seems to be
desperately missing). I often wish more methods were virtual in higher
level widgets, but I understand why conservatism is good in that regard.
>
> So, making widgets work in a declarative, GPU friendly world where easeof 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.
Again I think QQC2 completely missed the mark as far as "ease of
customization," in fact all you're apparently meant to customize IS the
look'n'feel in each theme... so not sure what kind of customizing you
mean there.
Anyway, so far I haven't heard a convincing argument on why any of the
drawing performance improvements couldn't have been implemented in
"QWidgets" or Graphics Framework. Then possibly they could be re-used in
QML. And/or have new "skinny" optimized QtQuick widgets built (the way
they are now anyway), which could then also be used in either
language/framework. Or even, yeah, why is it "impossible"/hard to just
use the QtQuickItems directly from C++ (as brought up on this thread I
think)?
I really did want to like QML to bridge the "gap" to the phone/tablet
UI, and the language and syntax and all that is fine, but in the end I
was very frustrated by the limited widget functionality and the
difficulty in customizing them (search for my MLDoubleSpinBox on GitHub
for an example of how ridiculous it can get to do so). I decided it's
easier to just write HTML/JS/CSS for the UI... with all of the zillions
of components already out there for it and support on basically any
device I'd be targeting with a rich 'universal" UI anyway (and could
still keep Qt backend which has pretty much everything to inject data
into JS structs/objects/vars). Seems maybe Qt was headed this way at one
point as well, but also nixed... too bad. But for "real desktop"
(pointer+keyboard) Qt applications with a bunch of controls and windows
or whatnot, QWidgets and Graphics Framework are still best IMHO, and can
even work fine on Android or small "single board" computers as well if
properly managed and run on modern (last 5-6 yrs) hardware.
Cheers,
-Max
More information about the Interest
mailing list