[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