Reputation: 145
How I can do following: I’d like show my main window on start on the center screen.
Upvotes: 11
Views: 19946
Reputation: 3045
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;
}
}
Upvotes: 2
Reputation: 1737
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
}
}
Upvotes: 30
Reputation: 4081
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).
Upvotes: 1
Reputation: 8698
After examining both replies and actually debugging the code with Qt 5.9.1 it shows more than one issue with original replies:
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).Window.screen
instead of Screen
singleton type. That way we get actual screen matching the window on.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.
Upvotes: 3
Reputation: 24386
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
}
}
Upvotes: 24
Reputation: 7687
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).
Upvotes: 1