Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to control which Screen a Window is shown in from QML

Tags:

qt

qml

My application has a main window with a button, and when I click the button I use createComponent to create a subclass of Window {} and show it (purely in QML). I am running the application on my macbook with another monitor attached.

If I do not attempt to set the .x or .y properties of my new window, then it is shown on top of my main window, whether the main window is on my macbook's screen or on the attached monitor (i.e. the new window is always shown on the same screen as the main window). However, if I do set the .x or .y properties of the new window (to any value at all), then the new window is always shown on the macbook screen, regardless of which screen I have my main window on.

How can I control which available screen my new Window is shown in? And related, how can I exactly control the positioning of the new window in the screen (for example, how can I have the new window always appear in the lower-right corner)?

Edit: basic code. RemoteWindow.qml:

Window {
    id: myWindow
    flags: Qt.Window | Qt.WindowTitleHint | Qt.WindowStaysOnTopHint 
        | Qt.WindowCloseButtonHint
    modality: Qt.NonModal
    height: 500
    width: 350

    // window contents, doesn't matter
}

In my main window, I have this function (remoteControl is a property that keeps a reference to the remote window):

function showRemoteWindow() {
    remoteControl.x = Screen.width - remoteControl.width
    remoteControl.y = Screen.height - remoteControl.height
    remoteControl.show()
}

Also on my main window I have a button, and in its onClicked: event I have this code:

if (remoteControl) {
    showRemoteWindow()
} else {
    var component = Qt.createComponent("RemoteWindow.qml")
    if (component.status === Component.Ready) {
        remoteControl = component.createObject(parent)
        showRemoteWindow() // window appears even without this call,
            // but calling this method to also set the initial position
    }
}

If I comment out the setting of .x and .y in the showRemoteWindow function, then my RemoteWindow always appears in the same screen as my main window (either the macbook screen or the attached monitor). But if I leave those two lines uncommented (or make any other attempt to set the x or y position of the window), then my RemoteWindow always appears on the macbook screen, regardless of which screen my main window is in.

like image 219
MusiGenesis Avatar asked Jul 14 '17 03:07

MusiGenesis


1 Answers

Like @Blabdouze said, there is now in Qt 5.9 a screen property for Window. You can assign it an element of the Qt.application.screens array.

If you want to display a window in the first screen you can do :

import QtQuick.Window 2.3 // the 2.3 is necessary

Window {
    //...
    screen: Qt.application.screens[0]
}

Assigning a screen to a window seems to position it at the center of the screen. If you want to finely control the window's position, you can use x and y instead of screen. For example if you want to display a window in the bottom left of the first screen :

Window {
    //...
    screen: Qt.application.screens[0] //assigning the window to the screen is not needed, but it makes the x and y binding more readable
    x: screen.virtualX
    y: screen.virtualY + screen.height - height
}

If you are not on Qt 5.9 yet, you could expose the screens array from c++ like so :

QList<QObject*> screens;
for (QScreen* screen : QGuiApplication::screens())
    screens.append(screen);
engine.rootContext()->setContextProperty("screens", QVariant::fromValue(screens));

And access the geometry of a screen with geometry/virtualGeometry instead of virtualX/virtualY :

x: screens[0].geometry.x
like image 122
GrecKo Avatar answered Sep 24 '22 07:09

GrecKo