我具有以下QML组件:
import QtQuick 2.3
import QtQuick.Window 2.3
Window
{
id: main
visible: true
width: 500
height: 500
screen: Qt.application.screens[0]
Text
{
text: "Hello World!"
}
}
使用以下方式:
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QString>
int main(int argc, char** argv)
{
QApplication app{argc, argv};
QQmlApplicationEngine engine;
engine.load(QUrl{QStringLiteral("qrc:/main.qml")});
return app.exec();
}
我正在两个屏幕的系统上运行它。
只要我拥有screen: Qt.application.screens[0]
,该窗口将始终在启动应用程序时显示在鼠标所在的屏幕上。
如果我将其更改为screen: Qt.application.screens[1]
,则无论当前鼠标位置如何,该窗口将始终显示在第二个屏幕上。
Qt.application.screens[2]
似乎不存在。
现在有两个问题:screen: Qt.application.screens[0]
的这种行为是否可预期,即该数组中的第一个元素是否始终是当前屏幕?
如果是的话,我实际上如何获得第一个屏幕?
已经在Qt版本5.9.6和5.12.3上进行了尝试。
答案 0 :(得分:1)
在两屏虚拟桌面上,我将尝试在指定屏幕之后立即设置窗口坐标。应该使用以下代码将窗口置于Qt.application.screens
数组的第一个屏幕中央:
screen: Qt.application.screens[0]
x: screen.virtualX + ((screen.width - width) / 2)
y: screen.virtualY + ((screen.height - height) / 2)
注意,我使用了virtualX
和virtualY
属性,即虚拟桌面内屏幕的坐标。这样,窗口将居中放置在其所属的任何屏幕上。
顺便说一句,可以完全省略screen
属性,仅设置坐标:
x: 0
y: 0
上面的代码会将窗口定位到左屏幕的左上角,即虚拟桌面的绝对左上角。
答案 1 :(得分:0)
如果我正确理解了这个问题,那么Qt.application.screens[0]
意味着只访问以下数组的第一个元素:https://doc.qt.io/qt-5/qguiapplication.html#screens。文档中没有描述此方法的QScreen实例的顺序,但是看起来第0个索引表示第一个屏幕。但是,还有另一种方法来获取第一个屏幕。但是,请记住,说“第一个屏幕”并不是完全正确的命名。您可以实际交换屏幕,然后哪个屏幕是第一个屏幕?您应该了解Qt不知道您是否已物理交换屏幕。因此,对于这种类型的屏幕有更正确的要求。 Qt将您可能视为第一个屏幕的屏幕称为主屏幕。访问该屏幕的方法如下:https://doc.qt.io/qt-5/qguiapplication.html#primaryScreen-prop
换句话说,可以通过以下方法满足您的需求:您应该使用screen: Qt.application.screens[0]
而不是screen: Qt.application.primaryScreen
。第一种方法也可能会起作用,但是primaryScreen的使用比第一种方法更具声明性和清晰度。
答案 2 :(得分:0)
该数组中的第一个元素是否始终是当前屏幕?
您可以自己检查数组,只需将以下代码放入Window
范围内即可:
Component.onCompleted: {
var screens = Qt.application.screens
for(var i in screens)
{
console.log("screens[" + i + "]")
for(var p in screens[i])
{
var member = screens[i][p]
if(typeof member !== "function")
{
console.log(" " + p + ": " + member)
}
}
}
}
除制造商/型号外,您可以通过它们的virtualX
和virtualY
属性来确定哪个屏幕(例如,如果您的虚拟桌面由两个1920x1080全高清屏幕并排组成) ,则左边的将有virtualX: 0
,右边的将有virtualX: 1920
)。
据我所知,数组不会更改以反映哪个窗口托管窗口:它应该镜像QGuiApplication::screens
列表,您也可以在main
中检查该列表,然后加载qml:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QScreen>
#include <QDebug>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
int id = 0;
for(QScreen * s : app.screens())
{
qDebug() << "[" << id++ << "]";
qDebug() << " geometry: " << s->geometry();
qDebug() << " primary: " << (app.primaryScreen() == s);
}
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}