[Development] Exposing QScreen API to QML
Samuel Rødal
samuel.rodal at nokia.com
Wed Nov 2 09:03:21 CET 2011
Hello,
I'm one of the guys who have been working on the Lighthouse API changes
for Qt 5 and new Qt 5 APIs like QWindow and QScreen. For those who are
not familiar, QWindow is the low-level Qt abstraction of a native window
that has its own rendering surface (native means whatever the Lighthouse
platform plugin provides, ie with the minimal plugin "native" currently
means a QImage backing store that simply gets saved as images to disk).
The QWidget stack and the scene graph both use QWindow as the
abstraction to get input and to get content onto the screen.
QScreen provides a way to query information (like geometry, dpi,
orientation, etc) about screens, and to move a window to a certain
screen with QWindow::setScreen(). QGuiApplication provides screens()
which returns a list of all the available screens, primaryScreen() which
returns the default screen, as well as the screenAdded() signal when a
new screen is connected. The QScreen header can be seen here:
https://qt.gitorious.org/qt/qtbase/blobs/master/src/gui/kernel/qscreen.h
Currently we're trying to find a nice way to expose the QScreen API to
QML. The obvious way of exposing the QGuiApplication properties /
signals as Qt.application.screens, Qt.application.primaryScreen, and
Qt.application.screenAdded doesn't work too well unfortunately, since
there's no way of finding out which screen the QQuickView belongs to
from QML, and the screen list is useless as there's no way to control
which screen you're on from QML at the moment. We could limit ourselves
to only allowing a single declarative context to only be associated with
one screen, but that prevents future use cases like controlling the UI
for both the main display and the external display from a single QML
file, which might be useful in for example presentation tools or video
players / gallery viewers where the main display shows some controls
that are not shown on the external display. In the future we might want
to support these use cases as well as better support desktop
applications by having a Window item or similar to be able to explicitly
create new top-level windows from QML (a similar feature is already
exposed in QML desktop components, but it sounds like it would be useful
to have a generic abstraction in the QML core).
Anyway, in the meantime the most future proof approach seems to be to
tie the screen information to an Item, instead of making it a global
property. The two approaches we're currently looking at is having a
ScreenInfo element, or using attached properties to dynamically insert a
Screen object with corresponding properties on demand.
Here's some example code for the two approaches:
Rectangle {
ScreenInfo {
id: screenInfo
onCurrentOrientationChanged: {
// do animation ...
}
}
width: 4.0 * screenInfo.physicalDotsPerInchX
height: 4.0 * screenInfo.physicalDotsPerInchY
}
Alternatively, with the attached property:
Rectangle {
width: 4.0 * Screen.physicalDotsPerInchX
height: 4.0 * Screen.physicalDotsPerInchY
Screen.onCurrentOrientationChanged: {
// do animation ...
}
}
The latter has less syntax, but it might be easier to create multiple
Screen objects. A way to solve that can be to compute the desired scale
factors etc once in a single element, and then re-use those factors in
child elements without accessing Screen directly.
Another question is whether the x and y DPI should be easily accessed by
a property that simply averages the two (square or mostly square pixels
seems to be the norm anyway). This might help make a UI that wants to
support both portrait and landscape orientation less confusing, as it
wouldn't have to manually swap the x and y properties when doing a 90
degree rotation.
Feedback is appreciated :)
--
Samuel
More information about the Development
mailing list