[Development] Exposing QScreen API to QML

lars.knoll at nokia.com lars.knoll at nokia.com
Tue Nov 8 21:17:10 CET 2011


On 11/7/11 9:21 AM, "ext Alan Alpert" <alan.alpert at nokia.com> wrote:

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

Any API for accessing screens should be in the QtQuick module. The engine
itself shouldn't really contain anything tied to Gui.

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

I'm not too fond of this. The reason is that I'd rather explicitly create
surfaces on a screen, than magically attach items in an existing view to a
screen.

I'll explain more in the thread about Window {}.

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

Yes, average values are really good to have. In most cases, DPI will be
the same in x and y anyway.


Cheers,
Lars




More information about the Development mailing list