2009-06-12 13 views
35

Voglio finestra principale di un'applicazione di ignorare gli eventi del mouse e della tastiera, passandoli alle applicazioni sottostanti nella finestra di gestione Z-ordine.Qt - widget di livello superiore con trasparenza di eventi tastiera e mouse?

Vedo come rendere i widget figlio ignorano gli eventi della tastiera o del mouse, ma per quanto riguarda la finestra principale?

che sto cercando di fare un widget desktop che si trova sempre e solo sullo sfondo ed è totalmente invisibile agli eventi di tastiera e mouse. (Passare attraverso)

Qt :: X11BypassWindowManagerHint mi fa passare attraverso la tastiera (anche se purtroppo X11 specifica, ma va bene per ora), così come su eventi del mouse?

Esiste un modo OS-agnostic per essere trasparente per gli eventi della tastiera?

EDIT:

La parola chiave qui è la trasparenza.

Non voglio EAT eventi di mouse e tastiera, voglio che il gestore di finestre sappia che non li voglio affatto. Questi eventi dovrebbero essere indirizzati a qualsiasi applicazione si trovi sotto di me nello zorder.

Per esempio, voglio essere in grado di fare clic su icone del desktop che sono coperti dal mio widget e interagire con loro, come se il widget non c'era.

+0

Uhh ... perché il voto negativo? – darron

+0

non ho idea del perché qualcuno abbia votato questa ... domanda perfettamente legittima. sfortunatamente non ho la risposta, ma sono abbastanza sicuro che sia là fuori perché se ricordo bene KDE ha questo tipo di widget sul desktop ed è basato su Qt. –

+0

Hai mai trovato la soluzione per Linux? – nilsge

risposta

1

Penso che imperativa dovrebbe funzionare:

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

che è un po 'di quello che dice la documentazione relativa alla classe QWidget sull'evento() funzione membro:

Questa funzione restituisce vero se il evento è stato riconosciuto, altrimenti restituisce false. Se l'evento riconosciuto è stata accettata (vedi QEvent :: accettato), ulteriori elaborazioni come evento propagazione al widget genitore fermate.

1

di event filters Usa Qt: essi permettono l'applicazione di mangiare a seconda di quale si specificano gli eventi (vale a dire di tastiera e mouse eventi), ma ancora elaborare altri eventi come eventi di vernice.

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

forse mi manca qualcosa qui, ma avete provato sottoclassi della classe QMainWindow e l'override del metodo QWidget::event() per restituire sempre false? Se hai bisogno di gestire alcuni eventi, puoi aggiungere anche quell'intelligenza.

Questa tecnica dovrebbe consentire di ispezionare gli eventi in arrivo per l'applicazione e ignorarli se lo si desidera, senza dover mangiare utilizzando un filtro eventi.

Se ciò non funziona, è possibile tentare di reindirizzare gli eventi sul desktop chiamando QCoreApplication::notify() e passando l'evento sul widget del desktop ottenuto chiamando QApplication::desktop().Non ho idea se questo avrebbe funzionato, ma sembrava che valesse la pena provare.

7

Forse quello che vuoi è

widget->setAttribute(Qt::WA_TransparentForMouseEvents) 

? Questo è ciò che QRubberBand usa per lasciare che sia il genitore a gestire gli eventi del mouse. Per quanto riguarda gli eventi di tastiera, un QWidget non ottiene alcun evento di tastiera a meno che non si sia impostato un focusPolicy().

setFocusPolicy(Qt::NoFocus); 

dovrebbe pertanto occuparsi degli eventi della tastiera.

+1

Ok, questo sta facendo esattamente quello che ho detto che so già come fare. Non voglio un widget che consente a "è il genitore di gestire gli eventi del mouse" ... Voglio che l'intera APPLICAZIONE li ignori. Voglio che qualcosa dica all'ambiente di finestre (X, WinXP, ecc.) Che un clic sulla mia app dovrebbe passare a un'altra app che si trova sotto di essa sull'ordine Z. Che digitando sulla tastiera dovrebbe fare lo stesso. Queste soluzioni passano solo eventi dal widget figlio al genitore. Voglio che gli eventi vengano inviati dal widget padre al gestore di finestre o, molto probabilmente, non vengano mai inviati all'app. – darron

+0

tuttavia, questa risposta è utile a qualcuno che potrebbe effettivamente voler fare ciò di cui stai parlando. (passa cose a un cliente). L'ho provato, nella remota possibilità che il framework Qt riconosca che stai tentando di ignorare gli eventi a livello di genitore e proverò a rinviarli al window manager (o ad impostare una sorta di flag nel window manager per bypassare) ... ma come previsto non ha funzionato. La mia app ha mangiato gli eventi. – darron

+0

Giusto, scusa. Da allora ho anche provato setMask(), che fa quello che vuoi, ma anche la visibilità delle clip. Sono abbastanza sicuro che non c'è modo di fare quello che vuoi, senza ricorrere agli hack specifici del sistema operativo. Hai trovato la funzionalità che cerchi in qualsiasi altra applicazione? –

10

In Windows è possibile impostare WS_EX_TRANSPARENT

Per fare questo in Qt utilizzare il seguente codice:

includere l'intestazione,

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

e inserire il seguente codice nel costruttore.

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

Wow !!! Funziona. :) Grazie mille JProgrammer. (+1) – zeFree

3

ho trovato la soluzione seguente (testato su Linux, funziona anche su Windows in base alle @TheSHEEEP):

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

E 'stato aggiunto nella recente rilascio più qt (non ho trovato quando) vedi http://doc.qt.io/qt-5/qt.html

+1

Funziona anche su Windows. – TheSHEEEP

+0

grazie per il test @TheSHEEEP – mxttie

Problemi correlati