import QtQuick 1.1

Published Friday February 25th, 2011
13 Comments on import QtQuick 1.1
Posted in Qt Quick

For those who have been following QML , you might remember that we changed the imports to QtQuick 1.0 to allow us minor revisions of the Qt Quick module in minor revisions of Qt. One of those minor revisions is nearly done, and will soon be waiting in the 4.7 branch of Qt. There’s a bunch of good stuff there and one area in particular I’d like to focus on is the improvements we’ve made to versioning.

Last year I mentioned that I was going to do a blog post on QML’s versioning system with my word game module. As it so happens, around that time we looked at the versioning system and saw that there were some features we were missing – those have been implemented for QtQuick 1.1 and provide a much nicer story for the versioning system as a whole. Let me tell you that story.

With QML modules we aimed to have a nicer upgrade path than is currently possible with C++. We’ve strived to allow changes between versions without causing the applications to break, or restricting the module owners to trivial changes. The core of this is the versioned module imports, which is why you import ‘QtQuick 1.1’ instead of just ‘QtQuick’. By picking a specific version we have a chance to give you just the version you asked for, even if the module has now advanced to a new version with new features. The primary mechanism for this is the version numbers in qmlRegisterType. When you specify the minor and major versions that a type is introduced in, the application has to import at least that version in order for the type to be added to the namespace. This means that the modules can add types without worrying about a symbol conflict.

As an example, I added a Letters type to the word game module. Let’s imagine the below snippet is from a game that used version 1.0:

import QtQuick 1.0
import MyTypes 1.0
import Qt.labs.wordgame 1.0
Item{
    BoardLogic{
        ...
    }
    Letters{
        count: 26
        ...
    }
}

The ‘Letters’ type in this case is one from the ‘MyTypes’ module, and might fulfill a similar role to the new type. But it has different properties, and so the error you get if you tried to run this file (with version 1.1 and without our versioning system) would be Cannot assign to non-existent property "test". If wordgame was a system module that was updated independently of the game, then the game would fail to launch until the game’s own update got rushed out.

But this specific snippet doesn’t import 1.1, it imports 1.0. So with our versioning system the new Letters type from wordgame does not get added, and the game runs as before. The application maintainer can easily fix this next version by changing their type name, or importing wordgame in a namespace (import Qt.labs.wordgame 1.1 as WordGame), in the same update where they actually use the functionality. And they don’t have a broken application in the interim.

Note that if you try to import an older version of the library than the one you are using to develop with, some errors cannot be warned about and it may not work when deployed against that older version. But it’s easy to work around this – develop with the version that you’re targeting.

A more radical example would be if you completely changed the implementation (which we’re doing for the next Qt.labs.particles release). By registering a different C++ class for the Type in a different version, then applications get the new type if and only if they import that version or later. They can still have the original class registered to that Type in the earlier version, and the class you get is determined by the version you import. So if the new approach doesn’t work out for you as well, you haven’t been screwed over by having the old version taken away from you.

But this is no longer the full story – in QtQuick 1.1 we have added versioning at the level of individual properties, signals, and slots. Versioned types is great, but it’s best suited for big sweeping changes like a new element or a full rewrite (which is practically a new element). You don’t want to have to make a whole new C++ class just to add a lineCount property to Text. And to get some use out of the Letters object in wordgame, it needed to integrate with BoardLogic; but that’s merely one property that tweaks the existing behavior. The below snippets from boardlogic.h shows just what was needed:

//A Letters object is how you can set the individual letter frequencies and score
Q_PROPERTY(Letters* letters READ letters WRITE setLetters NOTIFY lettersChanged REVISION 1);
...
signals:
Q_REVISION(1) void lettersChanged(Letters* arg);

Note that the getters and setters weren’t directly accessible from QML anyways, so don’t need the revision. And don’t forget to register the new revision in wordgame.cpp:

qmlRegisterType<BoardLogic,1>(uri,1,1,"BoardLogic");

Now the ‘letters’ property on BoardLogic only gets exposed to QML when you import version 1.1, avoiding the same sort of conflicts as was described for the type level. So it’s safe and easy to update system modules with just some extra properties/signals/slots without instantly breaking all the applications that rely on them.

With this level of version labeling, we’ve been able to actually make QtQuick 1.1 a minor release and one that shouldn’t break anyone’s running code. It fills in some functionality gaps without having to create a load of new classes – just adding some more properties where needed. And adds a couple of types too, but that’s another story.

Do you like this? Share it
Share on LinkedInGoogle+Share on FacebookTweet about this on Twitter

Posted in Qt Quick

13 comments

Dennis says:

Great feature, thanks!

One quick question, sorry if I misunderstood, but can you also replace the behavior of an existing property depending on the version?

Something like:

Q_PROPERTY(Letters* letters READ getBrokenLetters() WRITE setLetters NOTIFY lettersChanged REVISION 1);
Q_PROPERTY(Letters* letters READ getCorrectLetters() WRITE setLetters NOTIFY lettersChanged REVISION 2);

or would you need to register a different (possibly derived) class for that?

ABBAPOH says:

Will versioning functionality be added to QtCore?

aalpert says:

@Dennis I’m not sure if that would work, but the point of the revisions is not to split out bugfixes. If the behavior was broken, then fix it for all, if the behavior is changing, a different property makes sense.

@ABBAPOH This versioning functionality only makes sense for QML. So no.

smoggy says:

Could you give an example of :

“Other changes
Functions can be assigned to properties from JavaScript to create property bindings”

robert says:

Same question as smoggy. Can you give an example of what that means

@smoggy, robert

Here’s an example that imperatively sets up bindings that make the red square follow the mouse on clicking:

http://dpaste.org/huX4/

(excuse the URL, but I don’t know how to properly include code snippets in my comment and can’t see any link to instructions about that, nor do I think I could edit my post afterwards)

smoggy says:

Thx for the example Thorbjørn.

zbenjamin says:

I’m wondering if there will be real model support in
QML in the future. Only ListModel? That can not be enough
for real apps.

aalpert says:

@zbenjamin While this is nothing to do with 1.1, QtQuick has always had support for receiving QAbstractItemModels from C++ and using those from QML. So there is real model support in QML in the past and present, I expect the future to have it as well.

If you meant ‘pure QML’ then remember that QML is just meant to be the UI layer for full-sized applications. It’s amazing that you can write small applications purely in QML, but for many applications (especially on the desktop) you’ll still have C++ internals for the forseeable future.

@aalpert: what zbenjamin is saying is that it is limiting that there is no builtin grid/tree solution, I think. And I agree.

aalpert says:

@robin That’s views, not models ;).

It is a deficiency that there’s no built in Tree or Table view elements, you’ll need to write a custom view for those models once you expose them to QML. This is not a gap that has been filled in QtQuick 1.1, but we’re aware of the gap and hope to fill it eventually. I’m not aware of an existing JIRA item, so if you want to track the progress of a future TableView/TreeView you’ll need to file a suggestion.

blam says:

@zbenjamin, @robin There is future work scheduled to improve the model support in QML. If there are particular features of interest, though, we’d be interested in any details, if you do want to file a suggestion as mentioned by aalpert.

zbenjamin says:

@Robin Burchell thats almost what i meaned. I was not speaking about a finished treeview/gridview i was speaking about that there is no treeMODEL or tableMODEL with multiple columns in QML.

Commenting closed.

Get started today with Qt Download now