2009-06-12 12 views
35

Quiero una ventana principal de la aplicación para ignorar los eventos del mouse y del teclado, pasarlos a las aplicaciones debajo de él en el orden Z del administrador de ventanas.Qt: widget de nivel superior con transparencia de evento de teclado y mouse?

Veo cómo hacer widgets niño ignorar los eventos del teclado o el mouse, pero ¿qué hay de la ventana principal?

Estoy tratando de hacer un widget de escritorio que siempre se encuentra justo sobre el fondo y es totalmente invisible para los eventos de teclado y mouse. (Pase)

Qt :: X11BypassWindowManagerHint me atraviesa el teclado (aunque lamentablemente es específico de X11, pero está bien por ahora), entonces ¿qué hay de los eventos del mouse?

¿Hay una forma de agnóstica del sistema operativo para ser transparente a los eventos del teclado?

EDIT:

La palabra clave aquí es la transparencia.

No quiero COMER eventos de mouse y teclado, quiero que el administrador de ventanas sepa que no los quiero en absoluto. Esos eventos deben dirigirse a cualquier aplicación que esté debajo de mí en zorder.

Por ejemplo, quiero poder hacer clic en los iconos del escritorio que están cubiertos por mi widget e interactuar con ellos como si el widget no estuviera allí.

+0

Uhh ... ¿por qué el voto hacia abajo? – darron

+0

ni idea de por qué alguien ha votado esta ... pregunta perfectamente legítima. desafortunadamente no tengo la respuesta, pero estoy bastante seguro de que está ahí porque si no recuerdo mal, KDE tiene este tipo de widgets en el escritorio y está basado en Qt. –

+0

¿Alguna vez encontró la solución para Linux? – nilsge

Respuesta

1

Creo que primordial se supone que funciona:

bool YourMainWindow::event(QEvent *event) 
{ 
    event ->accept(); 
    return true; 
} 

que es algo de lo que la documentación de la clase QWidget dice acerca de eventos() función miembro:

Esta función devuelve verdadero si el evento fue reconocido, de lo contrario, devuelve falso. Si se aceptó el evento reconocido (consulte QEvent :: aceptado), se detiene cualquier procesamiento posterior, como el evento de propagación al widget principal .

1

de event filters uso de Qt: que le permitirá a su aplicación a comer lo que los eventos que especifique (es decir, los eventos de teclado y ratón), pero aún procesar otros eventos tales como eventos de pintura.

bool FilterObject::eventFilter(QObject* object, QEvent* event) 
{ 
    QKeyEvent* pKeyEvent = qobject_cast<QKeyEvent*>(event); 
    QMouseEvent* pMouseEvent = qobject_cast<QMouseEvent*>(event); 

    if (pKeyEvent || pMouseEvent) 
    { 
     // eat all keyboard and mouse events 
     return true; 
    } 

    return FilterObjectParent::eventFilter(object, event); 
} 
2

Tal vez me estoy perdiendo algo aquí, pero ¿ha tratado de subclases de la clase QMainWindow y reemplazando el método QWidget::event() para volver siempre es falsa? Si necesita manejar algunos eventos, puede agregar esa información también aquí.

Esta técnica debería permitirle inspeccionar los eventos que llegan a la aplicación e ignorarlos si lo desea sin tener que comerlos usando un filtro de eventos.

Si esto no funciona, puede intentar redirigir los eventos al escritorio llamando al QCoreApplication::notify() y pasando el evento al widget de escritorio obtenido llamando al QApplication::desktop().No tengo idea si esto funcionaría, pero parecía que valdría la pena intentarlo.

7

Tal vez lo que desea es

widget->setAttribute(Qt::WA_TransparentForMouseEvents) 

? Eso es lo que utiliza QRubberBand para que su padre maneje los eventos del mouse. En cuanto a los eventos de teclado, un QWidget no obtiene ningún evento de teclado a menos que se haya establecido un focusPolicy().

setFocusPolicy(Qt::NoFocus); 

por lo tanto, debe hacerse cargo de los eventos del teclado.

+1

Bien, esto está haciendo exactamente lo que dije que ya sé cómo hacer. No quiero un widget que permita que "su padre maneje los eventos del mouse" ... Quiero que toda la APLICACIÓN los ignore. Quiero que algo diga al entorno de ventanas (X, WinXP, etc.) que un clic en mi aplicación debería pasar a otra aplicación sentada debajo de ella en el orden Z. Que escribiendo en el teclado debería hacer lo mismo. Estas soluciones solo están transfiriendo eventos desde los widgets secundarios al padre. Quiero que los eventos que se envían desde el widget principal vuelvan al administrador de ventanas, o muy probablemente nunca se envíen a la aplicación. – darron

+0

sin embargo, esta respuesta es útil para alguien que realmente quiera hacer lo que está hablando. (pasar cosas a un cliente). Lo intenté, en la remota posibilidad de que el framework Qt realmente reconozca que está tratando de ignorar los eventos en el nivel principal y trataría de enviarlos de vuelta al administrador de ventanas (o establecer algún tipo de indicador en el administrador de ventanas para eludirlos)) ... pero como esperaba, no funcionó. Mi aplicación comió los eventos. – darron

+0

Bien, perdón. Desde entonces también he probado setMask(), que hace lo que quiere, pero también recorta la visibilidad. Estoy bastante seguro de que no hay forma de hacer lo que quieras, sin recurrir a los hacks específicos del sistema operativo. ¿Has encontrado la funcionalidad que buscas en cualquier otra aplicación? –

10

En Windows, puede establecer WS_EX_TRANSPARENT

Para hacer esto en Qt utilizar el siguiente código:

Incluir el encabezado,

#if _WIN32 
    #include <windows.h> 
#endif 

y poner el siguiente código en el constructor.

#if _WIN32 
    HWND hwnd = (HWND) winId(); 
    LONG styles = GetWindowLong(hwnd, GWL_EXSTYLE); 
    SetWindowLong(hwnd, GWL_EXSTYLE, styles | WS_EX_TRANSPARENT); 
#endif 
+0

¡Guau! Funciona. :) Muchas gracias JProgrammer. (+1) – zeFree

3

me encontré con la siguiente solución (probado en Linux, también funciona en Windows según @TheSHEEEP):

setWindowFlags(windowFlags() | Qt::WindowTransparentForInput); 

Se ha añadido en la versión qt más reciente (no encontré cuando) ver http://doc.qt.io/qt-5/qt.html

+1

También funciona en Windows. – TheSHEEEP

+0

gracias por probar @TheSHEEEP – mxttie

Cuestiones relacionadas