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

发布于 2024-12-28 06:07:36 字数 35 浏览 1 评论 0原文

我可以如何执行以下操作:我想在中央屏幕上显示我的主窗口。

How I can do following: I’d like show my main window on start on the center screen.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

↘人皮目录ツ 2025-01-04 06:07:36

如果使用 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
    }
}

If using QtQuick, it's possible to do that:

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
    }
}
墨小墨 2025-01-04 06:07:36

迪尔森的答案要好得多,特别是因为没有提到小部件......无论如何,这是他的答案的一个更简单的版本:

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
}

正如亚历山大提到的,这种绑定可能会导致奇怪的调整大小行为。因此,最好使用迪尔森的答案。我唯一要提到的是,在 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
    }
}

Dielson's answer is much better, especially since widgets weren't mentioned... anyway, here's an even simpler version of his answer:

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
}

As mentioned by Alexander, this binding can result in weird resizing behaviour. Because of that, it's better to use Dielson's answer. The only thing I'd mention is that it's not common to use setters in QML; some systems (I believe they're called property interceptors) even rely on properties being set to perform animations, for example. So the more common approach is as follows:

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
    }
}
绻影浮沉 2025-01-04 06:07:36

在检查了这两个回复并使用 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 属性的处理程序改变。

这个解决方案更完整,使用 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 如果是这样,我使用了从 Window 派生的 ApplicationWindow 类型,它应该与 Window 定位行为一致。

After examining both replies and actually debugging the code with Qt 5.9.1 it shows more than one issue with original replies:

  1. Cannot bind [x, y] to [width, height] unless we want to see strange effects with resizing.
  2. Even though [x, y] change in Component.onCompleted seems to be logical it does not work as expected with 2 monitors of different DPI (as on systems I currently develop on).
  3. Need to use Window.screen instead of Screen singleton type. That way we get actual screen matching the window on.
  4. To completely untie [x, y] from dynamic values but the actual window screen at the moment of the initial window showing we now use onScreenChanged which is a handler for the screen property change.

This solution is more complete and uses Window.screen property:

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. If so I used ApplicationWindow type which is derived from Window and it should be consistent with Window positioning behavior.

握住我的手 2025-01-04 06:07:36

缺少所有其他答案来考虑屏幕定位,可能导致窗口显示在错误的屏幕上。也许这曾经适用于以前版本的 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;
    }
}

All other answers are missing to take the screen positioning into account potentially causing the window to show up on the wrong screen. Maybe this used to work in previous version of Qt but it doesn't seem work with recent Qt versions anymore.

The following solution works for me with a multi-screen with different DPI setup (requires Qt 5.9 or later; tested with Qt 5.15 on macOS):

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;
    }
}
小巷里的女流氓 2025-01-04 06:07:36

您需要 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);
}

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

You'll need to setGeometry on your top-level widget before you show it. The easiest way I can think of to work out what geometry you need is via QDesktopWidget. Try the example below (create a QPushButton, press it while moving the widget around various screens) and you'll see what I mean:

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

Should be reasonably simple from there to come up with a generic version that works out a user's center screen (if it exists).

咽泪装欢 2025-01-04 06:07:36

亚历山大的回答几乎已经足够好了。但是,在 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();
    }
  }
}

这会在等待 10 毫秒后设置窗口的坐标(希望在这段时间 DE 已经完成其工作)。

Alexander's answer is almost good enough. However, on KDE I observe the following behaviour: the window is first opened on Monitor 1 and then is immediately moved to Monitor 2. In this situation, the referenced answer always forces the window to Monitor 1.

Since trying to detect this behaviour would probably require quite a bit of code, I just went for a simple solution by using a 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();
    }
  }
}

This sets the window's coordinates after waiting for 10ms (hopefully in that time the DE has done its job).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文