2008-09-15 75 views
3

我需要確定我的Qt 4.4.1應用程序何時獲得焦點。如何在Qt 4.4.1中檢測應用程序級別焦點?

我已經想出了兩種可能的解決方案,但它們都不能完全按照我的意願工作。

在第一種可能的解決方案中,我將qApp的focusChanged()信號連接到SLOT。在插槽中,我檢查'舊'指針。如果它爲'0',那麼我知道我們已經切換到這個應用程序,並且我做了我想要的。這似乎是讓應用程序檢測到這裏介紹的兩個解決方案的焦點的最可靠方法,但是遭受了下面描述的問題。

在第二種可能的解決方案中,我覆蓋了'focusInEvent()'例程,並且如果原因是'ActiveWindowFocusReason',請執行我想要的操作。

在這兩種解決方案中,代碼都是在我不想要的時候執行的。

例如,我有這樣的代碼,將覆蓋focusInEvent()例程:

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; 
    } 
    } 
} 

當這被執行,將出現QMessageBox提示對話框。但是,當通過按'yes'或'no'解除對話框時,該函數會立即再次被調用,因爲我認爲使用ActiveWindowFocusReason將焦點改回到當時的應用程序窗口。很明顯,我不希望發生這種情況。

同樣,如果用戶正在使用應用程序打開&關閉對話框和窗口等,我不希望這個例程激活。注意:雖然自從我嘗試了一下後,我並不確定這個例程被激活的情況,但它並不對所有對話框發生,儘管它至少出現在示例代碼中顯示的那個對話框中。

我只希望它在應用程序專注於此應用程序外部時激活,而不是在主窗口從其他對話窗口聚焦時激活。

這可能嗎?如何才能做到這一點?

感謝您提供任何信息,因爲這對我們的應用程序來說非常重要。

Raymond。

回答

0

看看Qt文檔,似乎每次小部件獲得焦點時都會創建焦點事件,因此您發佈的示例代碼不會出於您所述的原因。

我猜QApplication :: focusedChanged不能按照你想要的方式工作,因爲有些小部件不接受鍵盤事件,因此即使在同一個應用程序中改變焦點時,也會返回null作爲「舊」小部件。

我想知道您是否可以做任何的QApplication ::則activeWindow()

返回擁有鍵盤輸入焦點,或0,如果沒有應用程序窗口擁有焦點的應用程序頂級窗口。請注意,即使沒有focusWidget(),也可能存在activeWindow(),例如,如果窗口中沒有小部件接受關鍵事件。

1

當您的對話框打開時,鍵盤事件不會進入您的主窗口。對話結束後,他們會這樣做。這是一個焦點變化。如果您想忽略焦點從應用程序中的另一個窗口切換的情況,那麼您需要知道應用程序中的任何窗口何時具有焦點。創建一個變量併爲你的函數添加更多的邏輯。這需要小心,因爲在主窗口獲得焦點之前對話將失去焦點。

7

我認爲你需要跟蹤QEvent::ApplicationActivate事件。

您可以將event filter放在您的QApplication實例上,然後查找它。

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); 
    ... 
}