2008-09-15 4 views
3

Ich muss feststellen, wann meine Qt 4.4.1 Anwendung den Fokus erhält.Wie erkenne ich in Qt 4.4.1 Focus-In auf Anwendungsebene?

Ich habe zwei mögliche Lösungen gefunden, aber beide funktionieren nicht genau so, wie ich es möchte.

In der ersten möglichen Lösung, die eine Verbindung I focuschanged() Signals von qApp zu einem Schlitz. Im Slot überprüfe ich den "alten" Zeiger. Wenn es "0" ist, dann weiß ich, dass wir zu dieser Anwendung gewechselt haben und ich mache was ich will. Dies scheint die zuverlässigste Methode zu sein, die Anwendung dazu zu bringen, den Fokus der beiden hier vorgestellten Lösungen zu erkennen, leidet jedoch an dem unten beschriebenen Problem.

In der zweiten möglichen Lösung, overrode ich die ‚focusInEvent()‘ Routine, und tun, was ich, wenn der Grund wollen, ist ‚ActiveWindowFocusReason‘.

In diesen beiden Lösungen wird der Code zu Zeiten ausgeführt wird, wenn ich es sein, nicht will.

Zum Beispiel habe ich diesen Code haben, der die focusInEvent() Routine überschreibt:

void 
ApplicationWindow::focusInEvent(QFocusEvent* p_event) 
{ 

    Qt::FocusReason reason = p_event->reason(); 

    if(reason == Qt::ActiveWindowFocusReason && 
     hasNewUpstreamData()) 
    { 
    switch(QMessageBox::warning(this, "New Upstream Data Found!", 
            "New upstream data exists!\n" 
            "Do you want to refresh this simulation?", 
            "&Yes", "&No", 0, 0, 1)) 
    { 
    case 0: // Yes 
     refreshSimulation(); 
     break; 
    case 1: // No 
     break; 
    } 
    } 
} 

Wenn dies ausgeführt wird, wird das QMessageBox Dialog. Wenn der Dialog jedoch durch Drücken von entweder 'Ja' oder 'Nein' beendet wird, wird diese Funktion sofort erneut aufgerufen, da der Fokus zu diesem Zeitpunkt mit ActiveWindowFocusReason zurück in das Anwendungsfenster geändert wurde. Offensichtlich möchte ich nicht, dass das passiert.

Ebenso, wenn der Benutzer die Anwendung öffnet & Schließen von Dialogen und Fenstern usw., möchte ich diese Routine nicht aktivieren. HINWEIS: Ich bin mir nicht sicher, unter welchen Umständen diese Routine aktiviert ist, da ich ein bisschen probiert habe und es nicht für alle Fenster & Dialoge passiert, obwohl es zumindest für den im Beispielcode gezeigten Fall passiert .

Ich will es nur aktivieren, wenn die Anwendung von einem Ort außerhalb dieser Anwendung fokussiert ist, nicht, wenn das Hauptfenster von anderen Dialogfenstern in fokussiert ist.

Ist das möglich? Wie kann das gemacht werden?

Danke für jede Information, denn das ist sehr wichtig für unsere Anwendung zu tun.

Raymond.

Antwort

0

Mit Blick auf die Qt-Dokumentation es, dass die Fokus-Ereignisse scheint jedes Mal erstellt werden ein Widget den Fokus erhält, so dass der Beispielcode den Sie gebucht werden nicht aus den Gründen, arbeiten Sie angegeben.

Ich vermute, dass QApplication :: focusedChanged nicht wie gewünscht funktioniert, weil einige Widgets keine Tastaturereignisse akzeptieren, also auch null als "altes" Widget zurückgeben, auch wenn der Fokus innerhalb derselben App geändert wird.

Ich frage mich, ob Sie etwas mit QApplication tun können :: active()

Gibt die Anwendung Fenster der obersten Ebene, das die Tastatureingabefokus hat, oder 0, wenn kein Anwendungsfenster den Fokus hat. Beachten Sie, dass möglicherweise ein ActiveWindow() vorhanden ist, auch wenn focusWidget() nicht vorhanden ist, z. B. wenn kein Widget in diesem Fenster Schlüsselereignisse akzeptiert.

1

Wenn Ihr Dialogfeld geöffnet ist, werden Tastaturereignisse nicht in Ihr Hauptfenster verschoben. Nachdem der Dialog geschlossen wurde, tun sie es.Das ist eine Schwerpunktveränderung. Wenn Sie den Fall ignorieren möchten, in dem der Fokus von einem anderen Fenster in Ihrer Anwendung wechselte, müssen Sie wissen, wann ein Fenster in Ihrer Anwendung den Fokus hat. Machen Sie eine Variable und fügen Sie Ihrer Funktion etwas mehr Logik hinzu. Dies wird einige Vorsicht erfordern, da der Dialog den Fokus verliert, bevor das Hauptfenster fokussiert wird.

7

Ich denke, dass Sie das Ereignis QEvent::ApplicationActivate verfolgen müssen.

Sie können einen event filter auf Ihre QApplication-Instanz setzen und danach suchen.

bool 
ApplicationWindow::eventFilter(QObject * watched, QEvent * event) 
{ 
    if (watched != qApp) 
     goto finished; 

    if (event->type() != QEvent::ApplicationActivate) 
     goto finished; 

    // Invariant: we are now looking at an application activate event for 
    //   the application object 
    if (!hasNewUpstreamData()) 
     goto finished; 

    QMessageBox::StandardButton response = 
      QMessageBox::warning(this, "New Upstream Data Found!", 
            "New upstream data exists!\n" 
            "Do you want to refresh this simulation?", 
            QMessageBox::Yes | QMessageBox::No)); 

    if (response == QMessageBox::Yes) 
     refreshSimulation(); 

finished: 
    return <The-Superclass-here>::eventFilter(watched, event); 
} 

ApplicationWindow::ApplicationWindow(...) 
{ 
    if (qApp) 
     qApp->installEventFilter(this); 
    ... 
} 
Verwandte Themen