Qt Widgets or QtQuickControls?

I previously blogged about the progress Martin Klapetek and I since that I started another round of changes making sure the new Breeze theme works nicely with QtQuickControls.

It poses an interesting question; which should you use when making a new project?

With all the hype and excitement about QtQuick it’s hard to get a straight answer. The reality is there is no one single answer that fits everything.

In defence of using QWidgets

It’s alive and well

Reports of its death have been greatly exaggerated.

There are (at time of writing) over 1000 commits in the qtbase/widgets directory just since Qt5.0. It quite clearly is still supported and still maintained.

There are not a lot of new features being added, because there is not a lot else to add. From a developer POV this is a good thing as less things are going to break.

We have a huge library of assets

Our Frameworks have several widget based libraries; providing pre-built complex widgets from highlighted text editors, to kparts to buttons with integrated KAuth knowledge.

Discarding these and re-inventing these is not only wasteful and time consuming, but also going to result in many inconsistencies.

It’s easy to subclass and extend

The styling approaches are very different. In QWidget’s QStyle, styles supplied generic margin sizes and would draw generic frames and buttons.

In QtQuickControls styles are very very tied to the control; the style themes a button, or a combo box or checkbox explicitly.

Yesterday I tried to re-create the KColourButton in our KQuickAddons repository; the plan being to subclass the QtQuickControls Button and add a rectangle in the middle… something that should be ridiculously simple turned into an impossible mission; there’s just not information in the public API for the developer to get the margins from the theme. In order to fix this, I need to go and add extra API into Qt.

In support of QtQuickControls

There are some misnomers about QtQuickControls, mostly obvious:

QtQuickControls is for desktop, non-touch systems

QtQuickControls is destined to be the future replacements of widgets for
_all_ platforms. In 5.4 there is a theme for Android that fits in with the device including opening pickers for comboboxes.

Their is one style/backend for QtQuickControls that uses QStyle to replicate the desktop style. It is a stop-gap measure and not the main objective.

It’s rapidly getting better and better

If I was writing this article 6 months ago I would have written about how broken layouts were, I would have a whole paragraph about the difficulties in making the tab key work, I would have pages about blending in with existing widgets or the lack of dialogs. It is a very fast paced world, and each time I revisit the subject the list of places where QWidgets trumps QtQuick keeps falling.

Upstream are open to feedback

I have multiple changes in QtQuickControls already with a ever growing TODO list. If we put in the work we can shape the future of the widget replacements.

Mobile portability

With the android QtQuickControls landing soon, including native dialogs it’s very relevant for cross device applications.

Conclusions

I have absolutely no doubt that QtQuickControls is the future way of making applications. However it’s important to stress the word “future”.

Realistically, even though it’s possibly to get quick results in QML, it currently requires a lot more work to add in all the additional functionality that brings it on par with a QWidget application.

What I would like to see within the KDE community:

  • Thinking about your requirements and goals of a project before choosing which technology to use
  • Working upstream with Qt and frameworks to build a larger collection of re-usable components not just working within our applications
  • No regressions. The user shouldn’t care what tools a developer chose to use, they shouldn’t have to suffer for our technology shifts

Making Oxygen work with QtQuickControls

The backstory (an overly abridged history of drawing in Qt)

First we had QWidgets. They provided a set of easy to use components that you might put in an application; buttons, text inputs, combo boxes etc.

In order to make it look nice, as well as integrate on all platforms these widgets don’t actually do any drawing themselves. Instead they call a lot of methods in the relevant QStyle and ask the style to draw a frames, render some text, tell it how big spacing should be between various parts. There is an excellent talk about QStyles here.

Widgets a good for making forms, but they aren’t suited for drawing animations or custom shapes. So Qt has a framework QGraphicsView, which made it easy to render and manipulate pictures, text and shapes at a graphic level.

Dealing with all these objects in C++ still gets very complicated quickly, so Qt has a way on top of that to create and manipulate these objects using QML, to give us SceneGraph, which is a new underlying drawing technology which only allows use from QML.

QtQuickControls

QtQuick is a great platform, but we still need a way to draw traditional form components, we need a way to blend into the relevant platform and look like it belongs among the existing apps regardless of the technology used.

QtQuickControls provide a way to insert buttons, text, combo boxes etc. into your QtQuick application. Like in QWidgets, QtQuickControls do not do all the drawing themselves but instead have a QML powered style API for rendering/theming widgets.
This differs from the previous Qt Componenents approach in which platforms (such as PlasmaComponents) would redo all of the internal logic, input handling and drawing themselves.

In addition to providing a new style API, a “desktop” style is provided that talks between the QtQuickStyles API and the application QStyle. This means widgets in QtQuickControls will look the same as QWidgets. It works by providing a QML plugin that
can fetch style hints from QStyle, as well as render QStyle contents (such as frames and backgrounds) into textures that can be used from QtQuick.

Before

In theory, if we use QtQuickControls in a QML application and render it in Oxygen, everything will look perfect and “just work”.


In practice not so much. The code that makes QtQuickControls use QStyles is undertaking a very complex task and it’s very hard to think about all the different ways a style can be (ab)used to render content.

I, with the help of Martin Klapetek and Martin Gräßlin have been working on fixing these issues.
A lot of the work has been going upstream into fixing the code in QtQuickControls in Qt itself, with a few patches into Oxygen to help Oxygen know what type of widget it is styling.

After


There are still a few pixels off, but the result is usable for writing widgets or entire applications in QML in a way that fits in with the rest of the KDE applications.

Tracking Progress / Helping

Progress can be seen on the tracking wiki page. Due to timescales these changes will not be in Qt5.2.0 but as they are bugfixes, should be in Qt5.2.1.

Contact me if you want to help out, in addition it would really help us if someone with a self compiled Qt5 on Windows/Mac can help test our Qt patches to ensure we do not break anything; it will really help up our remaining upstream review requests which have not yet been merged.