8

我该怎么做:我想在中央屏幕上显示我的主窗口。

4

6 回答 6

27

如果使用 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
    }
}
于 2014-07-26T23:11:09.840 回答
21

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
    }
}
于 2014-10-17T11:26:13.867 回答
2

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

  1. 除非我们想看到调整大小的奇怪效果,否则无法将 [x, y] 绑定到 [width, height]。
  2. 尽管 [x, y] 的变化Component.onCompleted似乎是合乎逻辑的,但对于 2 个不同 DPI 的显示器(如我目前开发的系统),它并不能按预期工作。
  3. 需要使用Window.screen而不是Screen单例类型。这样我们就得到了与窗口匹配的实际屏幕。
  4. 为了将 [x, y] 从动态值中完全解开,但在显示初始窗口时的实际窗口屏幕,我们现在使用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
        }
    }
}

PS 如果是这样,我使用ApplicationWindow了派生自的类型,Window它应该与Window定位行为一致。

于 2018-09-24T22:30:18.193 回答
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);
}

从那里提出一个通用版本来计算用户的中心屏幕(如果存在)应该相当简单。

于 2012-01-23T13:35:07.740 回答
1

亚历山大的回答几乎已经足够好了。但是,在 KDE 上,我观察到以下行为:窗口首先在监视器 1 上打开,然后立即移动到监视器 2。在这种情况下,引用的答案总是强制窗口到监视器 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 已经完成了它的工作)。

于 2018-12-28T17:08:16.917 回答
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;
    }
}
于 2021-01-08T14:29:52.970 回答