【问题标题】:How to control which Screen a Window is shown in from QML如何从 QML 控制显示窗口的屏幕
【发布时间】:2017-07-14 03:07:07
【问题描述】:

我的应用程序有一个带有按钮的主窗口,当我单击该按钮时,我使用createComponent 创建Window {} 的子类并显示它(纯粹在QML 中)。我正在我的 Macbook 上运行该应用程序,并连接了另一台显示器。

如果我不尝试设置新窗口的.x.y 属性,那么无论主窗口是在我的macbook 屏幕上还是在连接的监视器上,它都会显示在我的主窗口顶部(即新窗口始终显示在与主窗口相同的屏幕上)。但是,如果我确实设置了新窗口的.x.y 属性(任何值),那么无论我的主窗口在哪个屏幕上,新窗口都会始终显示在macbook 屏幕上。

如何控制我的新窗口显示在哪个可用屏幕上?以及相关的,如何才能精确控制新窗口在屏幕中的位置(例如,如何让新窗口始终出现在右下角)?

编辑:基本代码。 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
}

在我的主窗口中,我有这个功能(remoteControl 是一个保留对远程窗口的引用的属性):

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

我的主窗口还有一个按钮,在它的onClicked: 事件中我有这个代码:

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

如果我在 showRemoteWindow 函数中注释掉 .x.y 的设置,那么我的 RemoteWindow 总是与我的主窗口(macbook 屏幕或连接的监视器)出现在同一个屏幕上。但是,如果我不注释这两行(或进行任何其他尝试设置窗口的 x 或 y 位置),那么无论我的主窗口在哪个屏幕上,我的 RemoteWindow always 都会出现在 macbook 屏幕上在里面。

【问题讨论】:

  • 我之前在 Qt 中处理过这些问题。多显示器是坚果。您能否分享您的代码,最好是作为一个最小可行的完整示例?
  • @selbie:添加了我的基本代码 sn-ps。抱歉,我正在开发的应用程序(遗留代码)非常庞大,很难解开其中的各个部分。
  • @MusiGenesis 您使用哪个版本的 Qt?在 Qt 5.9 中,他们在 Window 上添加了一个 screen 属性,这可能会满足您的需求。

标签: qt qml


【解决方案1】:

就像@Blabdouze 所说,现在在Qt 5.9 中有一个screen 属性用于Window。 您可以为其分配Qt.application.screens 数组的元素。

如果你想在第一个屏幕上显示一个窗口,你可以这样做:

import QtQuick.Window 2.3 // the 2.3 is necessary

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

将屏幕分配给窗口似乎会将其定位在屏幕的中心。 如果要精细控制窗口的位置,可以使用xy 代替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
}

如果您还没有使用 Qt 5.9,您可以像这样从 c++ 公开屏幕数组:

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

并使用geometry/virtualGeometry 而不是virtualX/virtualY 访问屏幕的几何图形:

x: screens[0].geometry.x

【讨论】:

  • 注意坐标(通常)是内容的角落。如果将 y 设置为顶部,则框架可能位于窗口之外。除非你将y设置为0,否则会自动移动到y = frameHeight...
  • 谢谢,我试试看。如果我不在 Qt 5.9 上,那么暴露屏幕的技巧(我的意思是作为补充)非常有用。我的公司目前正在使用 Qt 5.6 构建其应用程序,升级 Qt 是一个痛苦的官僚过程。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-06
  • 2017-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多