Tips and Tricks for QML

Tips and Tricks for QML

I would like to share some more information about how I resolve my QML issues. In my last post I got a friendly reply of hiding states and such information of a Component inside an Item of that component. This was a very good hint.

My application is making heavy use of delegates for the ListView, PathView, Repeater and sometimes qmlviewer stops displaying content with a warning: “QDeclarativeComponent: Component is not ready”. In contrast to the many other places this error message is not very helpful. In all of my cases this error came from a syntax error (unbalanced {}), using a duplicate property or having fun with lists. So check your model (if it is static) and your delegate file for syntax errors, e.g. load them in the qmlviewer and see if the error message is changing.
IIRC writing something like Rectangle { Item {} Item{} } is just a short form for writing Rectangle { data: [ Item {}, Item {} ] }. Now with the shortened way one does not need to use “,” at all, with the real list way, one may not have a “,” after the last item. It is good that the syntax checker is so strong, it just happens to conflict with my C99 usage.
The application requires some kind of table display and in general ListView/PathView do not allow such models. My not so unique idea was to have a ListModel and then another ListModel hanging off as an property. So the first approach might look like the one below.
import Qt 4.7
ListModel {
ListElement {
moreData: ListModel {}
}
}
But it is not supported by QML and you will get a nice error telling you that this is not possible. The workaround is to use the simple [] way to create a model that is working on the views.
import Qt 4.7
ListModel {
ListElement {
moreData: [
ListElement {}
]
}
}
With the above I can use a Repeater/ListView inside a Component/Delegate with a model of this row and I have a small table view. With my current approach I have to use a Flickable and two Repeaters increasing my memory usage but that is acceptable for now.
QML and dealing with states

QML and dealing with states

In the last days I have resumed my QML work (I had a small break to work on the MGCP GW code of OpenBSC to fix some real world issues) and there is one kind of issue I tend to run in and I wonder how others are solving it. Let us imagine we have a QML Component for a Button. The Button itself can hold a text (property alias text: buttonLabel.text) and the button has three states (enabled, focused, pressed) that depend on the MouseArea that inside the button as well. Actually this approach is directly coming from the many nice examples and demos provided by Nokia.

Now the problem is… I’m using the Button in many places and depending on some other external state the label of the Button should change and I keep writing things like this:
UI.Button {
id: text_button
text: ‘My Text’
MouseArea {
anchors.fill: parent
onClicked: { console.log(‘clicked’); }
}
states: [
State {
name: ‘some-state’
PropertyChanges {
target: text_button;
text: ‘Other text’; }
}
/* more states… */
]
}
And then I am going to wonder why things don’t work. The first issue is that my own MouseArea will receive the mouse click and the button will not work… but that is easily fixed. Do not add a custom MouseArea and have a clicked signal inside the button component. The second issue is with the states.. the above code is breaking the focus/pressed logic.

The way I am dealing with this kind of problem is to move the state into a parent and control the text from there. What is the proper way of solving this problem? Creating multiple buttons and control the visibility/opacity from outside? Duplicate the component states inside the custom states (cross product of my states and the component states)?
I know that talking about errors is bad as this will make people remember the wrong solution but I hope that other people stepping into these kind of problems will remember this as a possible problem..
First Steps with Qt’s Quick

First Steps with Qt’s Quick

I am very excited by the Qt Quick technology and I have finally found a reason to use it and gain some experience with it and want to report from my first hours of exploring it. The first time I have seen Declarative UI was with Enlightenment and the Edje framework. I liked it so much that I registered Epicenter five years ago. The plan was to create a handheld framework using declarative UI.

Now Qt Quick is not just a copy cat of Edje but adds some nice improvements over it. The first one is the usage of Javascript instead of the C like language, better integration with Qt’s Object Model (properties) and libraries/plugins. From my observation at Openmoko, our developers kept a set of C preprocessor macros around to do coming things with edje with Quick it seems to be better as one can import libraries and such.
The most common mistake I have made so far is dealing with the width/heigh of an Item. In my case I created an Item, placed a MouseArea (to deal with user input) of the size of the parent (anchors.fill: arent) in it and then also add some Text (as sibling). Now it appears possible that the Text is bigger than the parent item. For performance reasons no clipping is done by default so it renders just fine, just clicking doesn’t work. Which is bringing me to my debug trick…
I place a Rectangle { anchors.fill: parent; color: ‘blue’ } inside my item and then I actually see where it is. Another nice thing would be an Xray view showing the border of each item, their id but only in black and white. My solutions for this problem so far (from my first hours of using it) is to either use a Row/Column which seems to get the widh/heigt updated based on its children, or in some cases place a width/height inside the Item itself.
This is bringing me to the biggest issue with the qmlviewer and also an idea on how to resolve it… In the last couple of month’s I started to contribute to GNU Smalltalk and looking more into Self, Smalltalk-80 and such. The clever Xerox PARC people invented Model-View-Controller as part of Smalltalk-80, Qt adopted some parts of it with Qt4. In the meantime something called Morphic emerged. Morphich is a direct-manipulation User Interface. This means one is creating the UI inside a running UI by composing it from simple objects (just like Quick). In contrast to it one can inspect each element and interact with it, change it at runtime without restarting. This allows faster changes, and easier debugging in case something goes wrong. E.g. it easily answers the question of what is the width of that?
So for the immediate future I would like to see something like the WebKit inspector emerge for QML. This would allow to inspect the scene graph, change it from the console, has some simple hit testing to inspect one element, has the JavaScript Debugger and Profiler available, the timeline… and I am pretty sure to not be the first one to want it.