2011-03-24 14 views
5

Después de muchos meses de intentarlo, búsqueda, revisión de código, etc. Soy incapaz de encontrar una solución para posicionar correctamente una nueva ventana en QT. En mi caso más básico simplemente quiero obtener el tamaño final de la ventana y centrarlo debajo del ratón. Se desplazará para garantizar que ninguna parte de la ventana se encuentre fuera de la pantalla. No desea tener la ventana aparecen a continuación, pasar a su posición, que produce sacudidas visual, en particular con FX escritorio encendida.lugar Qt nueva ventana correctamente en pantalla, sobre el centro del ratón, se mueven en la pantalla

Los problemas que he encontrado, no todos los cuales tienen las soluciones adecuadas:

  1. frameGeometry no siempre se llena antes de la ventana se ha mostrado antes.

  2. frameGeometry es a veces totalmente erróneo, en particular, en Windows 7.

  3. Antes de mostrar que no es posible saber si sizeHint o el tamaño se aplicarán, o alguna otra cosa en el medio. Es decir, la política de tamaño no parece predecible.

Tenga en cuenta que sé cómo guardar/restaurar la geometría de una ventana creada anteriormente. A pesar de los defectos QT aquí también tengo una solución de trabajo.

También tenga en cuenta que no puedo utilizar la colocación por defecto gestor de ventanas. Para aplicaciones que no son IDM en una configuración multi-monitor de su colocación es terrible (a menudo ni siquiera estar en el mismo monitor como el ratón).

También me gustaría evitar sub-clasificar a todos los widgets y diálogos sólo para implementar la solución, ya que no sería genérico. Si esta es la única manera posible, entonces yo estaría dispuesto a considerarlo (filtros de eventos deben también no ser una opción).

¿Alguien tiene buenas soluciones viables?

+0

Ver mi última edición. La primera edición no fue segura. – TonyK

Respuesta

6

Editado mirar más científico: He cambiado el número arbitrario de llamadas a processEvents con un bucle que comprueba el valor de retorno.

Editado de nuevo: Parece que la nueva versión no es segura: puede quedarse atascada en el circuito. Así que puse un límite en el número de iteraciones.

Original:
Hábleme de ello. Si se me permite citar mi propio código:

// BIG PAIN: We want to get the dialog box to caluclate its own size. But there is 
// no simple way to do this. The following seems to work, but only if processEvents 
// is called at least twice. God knows why: 
setAttribute (Qt::WA_DontShowOnScreen, true) ; // Prevent screen flicker 
show() ; 

QEventLoop EventLoop (this) ; 
for (int i = 0 ; i < 10 ; i++) 
    if (!EventLoop.processEvents()) break ; 

hide() ; 
setAttribute (Qt::WA_DontShowOnScreen, false) ; 

int x = 99 ; // whatever 
int y = 99 ; // whatever 

// Make sure it fits on the screen 
QRect ScreenRect = qApp -> desktop() -> availableGeometry (ApplicationData -> mainWindow) ; 

if (x + frameGeometry().width() > ScreenRect.right()) 
    x = ScreenRect.right() - frameGeometry().width() ; 
if (x < ScreenRect.x()) x = ScreenRect.x() ; 

if (y + frameGeometry().height() > ScreenRect.bottom()) 
    y = ScreenRect.bottom() - frameGeometry().height() ; 
if (y < ScreenRect.y()) y = ScreenRect.y() ; 

move (x, y) ; 

probar esto, con diferentes números de las llamadas a processEvents. (En estas llamadas, los distintos subwidgets y subaplicaciones se dimensionan recursivamente)

+0

Gracias, realmente no noté antes el atributo "DontShowOnScreen". Desde el código que he visto y los informes de defectos de Qt sé por qué tienes que llamar a processEvents: hay una evaluación de tamaño vago, el código para producir un tamaño solo se llama en respuesta a ciertos eventos, como mostrar y cambiar el tamaño. Miré a través del código y aunque las funciones de tamaño sí existen, hay * ninguna * posibilidad de llamarlas directamente. –

+0

Así que intente esto en su lugar. – TonyK

+0

Sí, definitivamente implementaré y probaré ese primer bit: el resto del código de posicionamiento es casi el mismo que tengo ahora. –

-1

¿Ha intentado activar el diseño? Lo obliga a calcular los tamaños y las posiciones

QLayout :: activate()

después de esta llamada, sus widgets deben tener su tamaño correcto.

+2

Tengo, no ayuda. –

1

En cuanto al problema de no ser capaz de consultar una ventana para su tamaño antes de su puesto de manifiesto, hay una solución simple.Puede mover la ventana a un lugar muy alejado de la pantalla antes de mostrarlo. Por ejemplo, para centrar una ventana principal en la pantalla principal sin oscilar hago lo siguiente:

MainWindow mainWindow; 
QRect primaryScreenGeometry(QApplication::desktop()->screenGeometry()); 
mainWindow.move(-50000,-50000); 
mainWindow.show(); 
mainWindow.move((primaryScreenGeometry.width() - mainWindow.width())/2.0, 
       (primaryScreenGeometry.height() - mainWindow.height())/2.0); 

sólo lo he probado este código en Windows XP y Qt 4.8.x. Esperemos que también funcione en otras plataformas.

+0

Mi registro recibe spam con advertencias cuando hago esto: WindowsWindow :: setGeometryDp: no se puede establecer la geometría 450x394 + -50000 + -50000 – RvdK

+0

Pruebe algo más pequeño, o mejor aún, muévalo fuera del área visible en la computadora en funcionamiento para asegurarse funciona en cualquier configuración de monitor. –

+0

Eventualmente utilicé esta solución: http://stackoverflow.com/a/16690448/47351 – RvdK

Cuestiones relacionadas