我该如何做以下操作:我想在启动时将我的主窗口显示在屏幕中心。
如果使用QtQuick,就可以这样做:
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Window 2.0
ApplicationWindow {
visible: true
width: 320
height: 480
Component.onCompleted: {
// Commenting this to use properties instead of setters
//setX(Screen.width / 2 - width / 2);
//setY(Screen.height / 2 - height / 2);
x = Screen.width / 2 - width / 2
y = Screen.height / 2 - height / 2
}
}
Dielson的答案更好,尤其是因为没有提到小部件... 无论如何,这是他答案的更简单版本:
import QtQuick 2.0
import QtQuick.Window 2.0
Window {
visible: true
x: Screen.width / 2 - width / 2
y: Screen.height / 2 - height / 2
width: 320
height: 480
}
正如Alexander所提到的,这种绑定可能导致奇怪的调整行为。因此,最好使用 Dielson 的方法。我唯一要提到的是,在 QML 中使用 setter 不是常见的做法;甚至有些系统(我相信它们被称为属性拦截器)依赖于设置属性以执行动画等操作。所以更常见的方法如下:
import QtQuick 2.0
import QtQuick.Window 2.0
Window {
visible: true
width: 320
height: 480
Component.onCompleted: {
x = Screen.width / 2 - width / 2
y = Screen.height / 2 - height / 2
}
}
ApplicationWindow
,有一个screen
属性。 - Tomilov AnatoliyWindow
的 screen
属性。http://doc.qt.io/qt-5/qml-qtquick-window-window.html#screen-prop - Alexander V在检查了原始回复并实际调试了Qt 5.9.1代码后,发现以下问题:
Component.onCompleted
中更改 [x, y] 似乎是合理的,但在具有不同DPI的2个显示器上却没有按预期工作(如我目前开发的系统)。Window.screen
而非 Screen
单例类型。这样我们就能得到与窗口匹配的实际屏幕。onScreenChanged
,它是 screen
属性更改的处理程序。这种解决方案更完整,使用Window.screen属性:
ApplicationWindow {
id: window
property bool screenInit: false
title: qsTr("App Window Positioning")
visible: true
height: Theme.windowHeight // initial
width: Theme.windowWidth // initial
Connections {
target: window
onScreenChanged: if (!screenInit) {
// we have actual screen delivered here for the time when app starts
screenInit = true
window.x = screen.width / 2 - Theme.windowWidth / 2
window.y = screen.height / 2 - Theme.windowHeight / 2
}
}
}
顺便提一下,如果我使用的是从Window
派生出来的ApplicationWindow
类型,那么它应该与Window
的定位行为保持一致。
onScreenChanged
没有被调用。只有当窗口移动到另一个屏幕时才会被调用。可能会在某个时候更改这种情况。 - Ignitor在展示顶层widget前,您需要setGeometry
。我能想到的最简单的方法来确定所需的几何图形是通过QDesktopWidget
。尝试下面的例子(创建一个QPushButton
,同时移动widget到各个屏幕上),然后您就会明白我的意思:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->pushButton, SIGNAL(released()), this, SLOT(ButtonPressed()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::ButtonPressed()
{
qDebug() << QApplication::desktop()->screenCount();
qDebug() << QApplication::desktop()->screenNumber();
qDebug() << QApplication::desktop()->screenGeometry(this);
}
从那里开始,应该相对简单地设计出一个通用版本,以确定用户的中心屏幕(如果存在)。
亚历山大的回答几乎已经足够好了。然而,在KDE上,我观察到以下行为:窗口首先在显示器1上打开,然后立即移动到显示器2。在这种情况下,引用的答案总是强制窗口返回显示器1。
由于尝试检测此行为可能需要相当多的代码,因此我选择了使用定时器的简单解决方案:
ApplicationWindow {
id: window
visible: true
height: 320
width: 480
function setCoordinates() {
x += screen.width / 2 - width / 2
y += screen.height / 2 - height / 2
}
Timer {
id: timer
running: true
repeat: false
interval: 10
onTriggered: {
window.setCoordinates();
}
}
}
import QtQuick 2.9
import QtQuick.Window 2.9
Window {
id: root
visible: true
width: 320
height: 480
Component.onCompleted: {
root.x = root.screen.virtualX + root.screen.width / 2 - root.width / 2;
root.y = root.screen.virtualY + root.screen.height / 2 - root.height / 2;
}
}
screen
属性而不是Screen
单例。引用Screen
类型的文档:“请注意,在Component.onCompleted
时,Screen
类型无效,因为此时尚未在屏幕上显示Item
或Window
。” - Ignitor