[Development] Exposing QScreen API to QML

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


On Wed, 2 Nov 2011 18:03:21 ext Samuel Rødal wrote:
> 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

Looking at the QScreen header, would all of these properties really be 
constant? virtualSize and availableVirtualGeometry sound like they could 
change easily, as could logical size. If they can change, they'll need NOTIFY 
signals so that th bindings and update.

> 
> 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).

When you say QML core, you mean this should go in the QtQuick module? Or into 
the engine, and be available without an import statement? The QtQuick module 
is my preference.

My first guess is that it would need to hook into QQuickCanvas to easily find 
its QWindow* (for screen()) and to be notified of screen changes. That could 
affect where it can be placed. But if they're all in the QtDeclarative library 
then it's quite easy for it to work closely with the canvas to achieve this.

>
> 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.

I like the idea of the attached object, it's a cleaner looking API and the 
docs can explain the performance implications. 

> 
> 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.

I'd agree that a convenience physicalDotsPerInch/logicalDotsPerInch with 
average values would be helpful, while there are a lot of properties already 
I'd think that adding these (so you can choose X,Y or average) would still be 
alright.

-- 
Alan Alpert
Senior Engineer
Nokia, Qt Development Frameworks



More information about the Development mailing list