[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