QML - 启动时的主窗口位置(屏幕中心)

时间:2012-01-23 11:16:52

标签: c++ qt qml qt-quick

我如何做以下操作:我想在中心屏幕上显示我的主窗口。

6 个答案:

答案 0 :(得分:19)

如果使用QtQuick,可以这样做:

import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Window 2.0

ApplicationWindow {
    visible: true
    width: 320
    height: 480
    Component.onCompleted: {
        setX(Screen.width / 2 - width / 2);
        setY(Screen.height / 2 - height / 2);
    }
}

答案 1 :(得分:18)

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
}

如亚历山大所述,这种绑定可能会导致奇怪的大小调整行为。因此,使用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
    }
}

答案 2 :(得分:1)

在显示顶级窗口小部件之前,您需要setGeometry。我能想到的最简单的方法是通过QDesktopWidget计算出你需要的几何体。试试下面的例子(创建一个QPushButton,在围绕各种屏幕移动小部件的同时按下它),你会看到我的意思:

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

从那里可以相当简单地提出一个能够解决用户中心屏幕的通用版本(如果存在)。

答案 3 :(得分:1)

在检查了两个答复并使用Qt 5.9.1实际调试代码后,它显示了多个原始答复问题:

  1. 除非我们希望通过调整大小看到奇怪的效果,否则无法将[x,y]绑定到[width,height]。
  2. 即使Component.onCompleted中的[x,y]变化似乎是合乎逻辑的,但对于2个不同DPI的监视器(如我当前开发的系统),它还是无法按预期工作。
  3. 需要使用Window.screen而不是Screen单例类型。这样,我们就能获得与窗口匹配的实际屏幕。
  4. 要使[x,y]与动态值完全脱开,但在显示初始窗口时的实际窗口屏幕中,我们现在使用onScreenChanged,它是screen属性更改的处理程序。 / li>

此解决方案更完整,并使用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
        }
    }
}

P.S。如果是这样,我使用了ApplicationWindow的类型,该类型是从Window派生的,它应该与Window的定位行为保持一致。

答案 4 :(得分:1)

Alexander's answer差不多够用了。但是,在KDE上,我观察到以下行为:窗口首先在Monitor 1上打开,然后立即移至Monitor2。在这种情况下,引用的答案始终将窗口强制为Monitor 1。

由于尝试检测这种行为可能需要大量代码,因此我只是通过使用Timer来寻求简单的解决方案:

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();
    }
  }
}

这将在等待10毫秒后设置窗口的坐标(希望DE在此期间完成其工作)。

答案 5 :(得分:0)

所有其他答案都没有考虑到屏幕定位,这可能会导致窗口显示在错误的屏幕上。也许这曾经适用于以前版本的 Qt,但它似乎不再适用于最近的 Qt 版本。

以下解决方案适用于具有不同 DPI 设置的多屏幕(需要 Qt 5.9 或更高版本;在 macOS 上使用 Qt 5.15 测试):

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