[Development] Window{} API for QML

Alan Alpert alan.alpert at nokia.com
Mon Nov 7 09:32:21 CET 2011


Samuel's mail about exposing QScreen API mentions that a Window element might 
be useful to have in QML, and I concur. One area where you cannot really avoid 
splitting your UI across multiple windows is for multiple screens (e.g. an 
external display), and without a basic window abstraction in QML you have a 
very poor approach available to you for multi-screen apps in QML (you have to 
have two completely separate QQuickView's and pass data between via C++).

Given that there can be Desktop Components providing the full API for desktop 
windows (and this is being discussed on the qt-components ML already), I 
propose the following minimal Window{} API for QML core (i.e. inside the 
QtDeclarative library)

Window {//Inherits QQuickItem
    property string title: "untitled"
    property bool fullscreen: true
    
    property int x
    property int y
    property int width
    property int height
    property bool visible
}

Now this item would end up being reparented into another QQuickCanvas on 
another window after being created in the same engine as the main file. This 
allows bindings to work between windows just fine. Because of the reparenting 
though there are a few changes from QQuickItem which is why I've duplicated 
x/y/width/height/visible. Arguably it shouldn't be a QQuickItem because of 
this, but I think the easy access to anchors is worth it.

These properties would now refer to the attributes of the window, and be a 
two-way binding similar to QQuickView. x/y/width/height would refer to the 
geometry of the window and would update when window geometry changes. x/y 
would be relative to 0,0 on the parent window, allowing anchors to the root 
item of that window to work out properly. And visible would refer to the 
window's shown/hide status.

Doing Windows in QML via an element created in the main scene makes the engine 
sharing and bindings a lot easier and more useful. To place it on another 
screen, my current idea is that it would expose the QQuickCanvas (a QWindow 
subclass) in C++ and you could just set the screen from there. It'd be better 
not to have to expose the C++ class as public API, but since the screen 
assignment ought to happen in C++ I don't think it can be avoided. The C++ 
API, aside from the above properties, would just be the one function, 
QQuickCanvas* canvas(), to get the canvas for alterations (such as setScreen).

There's a prototype of the more extensive desktop version Window{} in 
https://qt.gitorious.org/~aalpert/qt-components/aalperts-desktop-components , 
it's the same approach just with more properties and fewer tests ;) . It's at 
least a PoC that show the engine sharing and reparenting works (except for 
text rendering, because the texture cache isn't shared right between canvases 
right now, but that's fixable). Writing that brings up two discussion points.

The first was that this approach isn't a QMainWindow like the old desktop 
components Window{}, and this breaks integrating QWidget menus/toolbars. 
Ideally we'd want to throw those out of desktop components and replace them 
with QML versions, but no-one has really looked into that yet. If anyone has 
ideas on how to do menus really well in QML I'd love to see an ML thread on 
that :) (remember that the reason QML doesn't have much for desktop yet is not 
because it has something against desktops, it's because no-one has had the 
time to look into it yet).

The second is that this approach differentiates between the initial view 
window and the secondary windows created in QML. There is no API to reposition 
or modify the initial window, and I contend that is the correct approach. The 
first window is created from C++ either by a custom application (which can set 
all these things itself), a program using QML like a scripting language (where 
they don't want you screwing with it - might even want to disable Window{}) or 
qmlscene/qmlobserver (which is only for debugging or prototyping). I think the 
control of the primary window should remain with the QML launch point, and the 
Window{} should go in a separate import so that it can be blocked by 
environments that want more rigid control.

I'd appreciate feedback on this API before it gets into Qt - we only want the 
highest quality APIs after all. In particular it'd be nice to have some 
feedback from desktop QML users. While I don't have time to write the desktop 
Window{} myself, it should be enabled as much as possible so that it's easy to 
write when someone finally finds the time. And ideally it shouldn't suffer a 
horrible API because no-one thought of desktop at the offset ;) .

-- 
Alan Alpert
Senior Engineer
Nokia, Qt Development Frameworks



More information about the Development mailing list