[Development] QML import versions

Alan Alpert 416365416c at gmail.com
Fri Sep 18 20:13:00 CEST 2015

On Fri, Sep 18, 2015 at 8:12 AM, Nurmi J-P <jpnurmi at theqtcompany.com> wrote:
> Hi all,
> I'd like to propose that all QML imports that are part of the Qt Essentials start following the respective Qt version number.
> Let's take a look at the version history of some of the QtQml and QtQuick imports.

You missed a few key ones at the beginning:

### Qt 4.7.0

- Qt 4.7

### Qt 4.7.1

- QtQuick 1.0

### Qt 4.7.4

- QtQuick 1.1

> ### Qt 5.0
> - QtQml 2.0
> - QtQuick 2.0
> - QtQuick.Particles 2.0
> In the beginning, everything was cute, fluffy, and consistent.

QtQuick 1.1 was still around, just wholly incompatible with the
previous modules (something we'd like to avoid in the future). That's
why QtQuick.Particles started at 2.x, because series 1 was still
active (and there is a QtQuick.Particles 1.0 implementation somewhere

Note also that around the Qt 5.0 release, and ever since, there were a
lot of discussions about getting back to the Qt version number. Sadly
I can't seem to find the emails right now. I seem to recall that the
Qt Mobility modules went that direction in Qt 4.7 times (I'll need
someone else to tell the story of how that went).

> ### Qt 5.1
> A big pile of new stuff was introduced in Qt 5.1. The versioning of some modules started from 1.0, whereas QtQml.Models adapted the version from the QtQml "parent" import.

> - QtQml 2.1 (++)
> - QtQml.Models 2.1 (new)

IMHO, this should have been 1.0. I'm probably the one who made the
mistake though, and just wasn't thinking about it.

> - QtQuick 2.1 (++)
> - QtQuick.Particles 2.0
> - QtQuick.Controls 1.0 (new)
> - QtQuick.Layouts 1.0 (new)
> - QtQuick.Dialogs 1.0 (new)
> ### Qt 5.2
> QtQml.Models goes already goes out of sync with QtQml.
> - QtQml 2.2 (++)
> - QtQml.Models 2.1
> - QtQuick 2.2 (++)
> - QtQuick.Particles 2.0
> - QtQuick.Controls 1.1 (++)
> - QtQuick.Layouts 1.1 (++)
> - QtQuick.Dialogs 1.1 (++)
> ### Qt 5.3
> QtQml goes out of sync with QtQuick and the minor version of Qt. QtQuick.Layouts goes out of sync with QtQuick.Controls & QtQuick.Dialogs siblings.
> - QtQml 2.2
> - QtQml.Models 2.1
> - QtQuick 2.3 (++)
> - QtQuick.Particles 2.0
> - QtQuick.Controls 1.2 (++)
> - QtQuick.Layouts 1.1
> - QtQuick.Dialogs 1.2 (++)
> ### Qt 5.4
> At this point QtQuick.Controls, QtQuick.Layouts, and QtQuick.Dialogs all have different versions.
> - QtQml 2.2
> - QtQml.Models 2.1
> - QtQuick 2.4 (++)
> - QtQuick.Particles 2.0
> - QtQuick.Controls 1.3 (++)
> - QtQuick.Layouts 1.1
> - QtQuick.Dialogs 1.2
> ### Qt 5.5
> QtQml.Models catches up and is back in sync with the QtQml "parent" import.
> - QtQml 2.2
> - QtQml.Models 2.2 (++)
> - QtQuick 2.5 (++)
> - QtQuick.Particles 2.0
> - QtQuick.Controls 1.4 (++)
> - QtQuick.Layouts 1.2 (++)
> - QtQuick.Dialogs 1.2
> ### Qt 5.6
> This time QtQml.Models surpasses the QtQml parent import version.
> - QtQml 2.2
> - QtQml.Models 2.3 (++)
> - QtQuick 2.6 (++)
> - QtQuick.Particles 2.0
> - QtQuick.Controls 1.5 (++)
> - QtQuick.Layouts 1.3 (++)
> - QtQuick.Dialogs 1.2
> Everyone can judge by themselves how coherent this looks like. :) A while ago the Qt Creator team needed help (QTCREATORBUG-14575) figuring out the available import versions in different Qt releases. I had lost track a long ago, so I actually had to read git log to find out. Now imagine a poor new user that installs Qt. It might not always be the latest available version, but specified by the project. How are they supposed to navigate in this jungle of QML versions?

They use the version with the features they need, instead of trying to
use a "latest" which they may not need? For users and Qt Creator
purposes we've discussed keeping a mapping or a wiki page, but that
never seemed to get off the ground. If we could keep the .qmltypes
files up to date, then that could be a viable mechanism too.

> What makes the situation even more cumbersome, to ourselves who develop these modules, is that there's no convention on how new properties are revisioned. Some classes are using a running revision number that gets incremented whenever new members are added, whereas others match it with the minor version of the module or Qt.

The former is the "official" convention (not that I know where it's
documented ;) ). As it's an internal development detail I'm not
surprised it's slipped through code review.

> - QQuickImage
>   - rev 1 in QtQuick 2.3
>   - rev 2 in QtQuick 2.5
> - QQuickMouseArea
>   - rev 1 in QtQuick 2.4
>   - rev 2 in QtQuick 2.5
> - QQuickText
>   - rev 2 in QtQuick 2.2
>   - rev 3 in QtQuick 2.3
>   - rev 6 in QtQuick 2.6
> Now, mix meta revisions with inheritance and it gets interesting...
> Therefore, I'm throwing in this proposal to
> 1) make all Qt Essentials QML modules follow the Qt version number, and
> 2) revision new properties using the minor version of Qt.
> Then Qt users have some clue what to import and what Qt version their app depends on, and Qt developers can instantly see when certain properties and methods were introduced while browsing the header files.
> Is this something that would be possible to implement already in Qt 5, or is this Qt 6 material? Does someone strongly oppose the idea? How often do we release new major versions of QML modules? I don't see why QML modules couldn't follow the same practices than the rest of Qt follows. Ironically, we've been working on this thing called Qt Quick Controls 2.0... :P

So what's not possible is the conceptual conflict between arbitrary
and semantic version numbers. With QtQml.Particles still at 2.0 in Qt
5.6 you know that it hasn't gained any new features and so your
particles scenes from 5.4 can be easily brought back to 5.2 if needed
for another deployment. With QtQuick at 2.6 you'd need to check you
aren't using any new features. But if QtQuick goes to 2.7 in 5.7 you
can either A) keep importing 2.6 and it works fine B) import 2.7 and
see if you have a name collision with a new feature. Since it didn't
bump the major version, you know all the existing features will keep
working as before (save for bug fixes) but at 3.0 all bets are off.

With the QtQuick module specifically, we probably can match the Qt
version just fine. The development pace of that module follows the
development pace of Qt. But the other modules tend to be developed
slower, leading to the following potential breaches of semantic

-Bumping QtQuick.Particles to 2.7 and raising everyone's hopes that
there was a new feature. Also in the current implementation of QML
versions this would require a code change to QtQuick.Particles
specific for 2.7 (and so another change every minor version...).
Because it requires a change for every valid minor version, if we just
did it for 2.7 then import QtQuick.Particles 2.6 would fail, but
import QtQuick.Particles 2.7 would not.
-Bumping QtQml to 3.0/6.0 at Qt 6 time, even though there probably
will NOT be any breaking changes at the core language elements level.
By saying "yeah, switch to 3.0 and nothing's changed" we've ruined the
semantic meaning of a major version change. In the current
implementation of QML you would need to duplicate all qmlRegister*
calls in order to do this.
-Not being able to bump QtQuick.Window to 3.0 before QtQuick, as Robin
explained. So either we delay development of that module or we have a
"minor" version bump which breaks existing elements (again, ruining
semantic versioning). I think it's technically possible to do that
with the current implementation, but it's a real pain because you'd
have to replace every single type, some with an uncreateable type
saying "not available anymore".

The other thing to consider is that QML versioning is not intended to
keep up with Qt version number *within an application*. So let's
imagine a scenario where every QML module in Qt essentials used the Qt
release version number since the dawn of time. You'd still have code
looking like this inside an application:

import QtQuick 5.5
import QtQuick.Particles 5.3
import QtQml.Models 5.3

It could be running against 6.1, but was developed against 5.6 most
recently. Since they aren't using QtQuick features added in 5.6,
there's no need to change the import, the most recent features they
used from QtQuick came from 5.5. They originally developed it against
5.3, and haven't used anything new from QtQuick.Particles or
QtQml.Models since. This is the sort of thing we'd be seeing if
QtCreator from Qt 5.3 could automatically pick the most recent import
for you when creating a project.

It would be nice to have an easy way to find out which module versions
are in which release. I think qmltypes is a better way of doing that,
because the semantic versioning is both valuable and deeply integrated
into the current system.

Alan Alpert

More information about the Development mailing list