QML: posición de la ventana principal al inicio (centro de la pantalla)
Pregunta
¿Cómo puedo hacer lo siguiente?Me gustaría mostrar mi ventana principal al inicio en la pantalla central.
Solución
Necesitarás setGeometry
en su widget de nivel superior antes de mostrarlo.La forma más fácil que se me ocurre para determinar qué geometría necesitas es a través de QDesktopWidget
.Pruebe el siguiente ejemplo (cree un QPushButton
, presiónelo mientras mueve el widget por varias pantallas) y verá lo que quiero decir:
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);
}
A partir de ahí, debería ser razonablemente sencillo crear una versión genérica que funcione en la pantalla central del usuario (si existe).
Otros consejos
Si usa Qtquick, es posible hacer eso:
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);
}
}
Dielson es mucho mejor, especialmente porque los widgets no se mencionaron ... de todos modos, aquí hay una versión aún más sencilla de su respuesta:
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
}
Como se mencionó por Alexander, esta unión puede resultar en un comportamiento de tamaño raro.Debido a eso, es mejor usar la respuesta de Dielson.Lo único que mencionaría es que no es común usar los colonos en QML;Algunos sistemas (creo que se llaman interceptores de propiedades) incluso confían en las propiedades que se están configurando para realizar animaciones, por ejemplo.Así que el enfoque más común es el siguiente:
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
}
}
Después de examinar ambas respuestas y depurar el código con Qt 5.9.1, muestra más de un problema con las respuestas originales:
- No se puede vincular [x, y] a [ancho, alto] a menos que queramos ver efectos extraños al cambiar el tamaño.
- Aunque [x, y] cambian en
Component.onCompleted
Parece lógico que no funcione como se esperaba con 2 monitores de diferentes DPI (como en los sistemas en los que desarrollo actualmente). - Necesitará usar
Window.screen
en lugar deScreen
tipo singleton.De esa manera obtenemos una pantalla real que coincide con la ventana. - Para desatar completamente [x, y] de los valores dinámicos pero la pantalla de la ventana real en el momento de la ventana inicial que se muestra ahora usamos
onScreenChanged
que es un controlador para elscreen
cambio de propiedad.
Esta solución es más completa y utiliza Pantalla de la ventana propiedad:
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
}
}
}
PDSi es así, usé ApplicationWindow
tipo que se deriva de Window
y debe ser consistente con Window
comportamiento de posicionamiento.
La respuesta de Alexander es lo suficientemente buena.Sin embargo, en KDE, observo el siguiente comportamiento: la ventana se abre por primera vez en el monitor 1 y luego se mueve inmediatamente al monitor 2. En esta situación, la respuesta de referencia siempre obliga a la ventana a monitorear 1.
Dado que tratar de detectar este comportamiento probablemente requeriría un poco de código, simplemente fui a una solución simple utilizando un temporizador:
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();
}
}
}
Esto establece las coordenadas de la ventana después de esperar durante 10ms (con suerte, en ese momento, el DE ha hecho su trabajo).