2010-01-05 42 views
2

我目前正在開發一個應用程序,啓動顯示其他對話框的單獨進程。我試圖實現的功能是模擬這些對話框的模態行爲。更具體地說,我需要應用程序在啓動對話框時停止處理所有輸入,鼠標和鍵盤,並在關閉時恢復。Qt應用程序:模擬模態行爲(啓用/禁用用戶輸入)

雖然如果你能夠建議如何做到這一點而不求助於Always-On-Top行爲,那麼這對對話並不是很重要,儘管如此,這也會很好。

要注意,該應用程序是在Windows和Linux下編譯的。另外,它不是直接啓動對話框的選項。它們在單獨的可執行文件中。此外,該應用程序是一個非常複雜的軟件,因此單獨禁用小部件不是一種選擇,或者至少不是一個可行的方法。

我找到了lock()unlock()在Qt 3.3中的QApplication類中的函數。我們目前正在使用Qt 4.5,它似乎沒有API。事實上,Qt 4.5 QApplication類似乎並沒有提供對Event Loop的訪問。

總結:如何在Qt應用程序中禁用/啓用用戶輸入,包括鼠標和鍵盤快捷鍵?

回答

4

要全面訪問應用程序範圍內的事件,請在您的應用程序對象上使用QObject::installEventFilter()QCoreApplication::setEventFilter()
如果你的過濾函數返回true,Qt停止進一步處理事件。

爲了不將平臺特定的事件轉發給其他應用程序,我會選擇合適的IPC機制。

+0

謝謝,剛剛發現這一點我自己大約10分鐘前。奇蹟般有效。順便說一句, – 2010-01-06 01:02:28

+2

。 _setEventFilter()_不是一個好主意。它似乎永久設置了事件過濾器。 _QObject :: installEventFilter()_和_QObject :: removeEventFilter()_對我更好。參考:http://doc.trolltech.com/4.5/eventsandfilters.html – 2010-01-06 01:07:30

+0

確保你沒有全局阻塞事件,如果你這樣做,如果你真的想要一些互動仍然工作(如線程之間的信號/插槽,等等)。 – 2010-01-06 17:22:14

1

作爲替代答案,您可以創建自己的事件循環,並在必要時開始運行它。您需要創建一個QEventLoop對象,將來自另一個進程的信號連接到其quit()插槽(例如,您正在運行其他程序的QProcess),然後連接exec()循環。如果我正確地閱讀了東西,那麼當循環運行時,主事件循環將不會處理任何東西。

+0

當然,你必須小心,並確保繪畫事件仍然正確處理。否則,如果您嘗試移動子對話框,主應用程序看起來像一團糟。雖然有趣的方法。 – 2010-01-07 00:22:06

3

GJ已經提出這個解決辦法,但我想我會貼上我的實現僅供參考:

實施,將吸收用戶的輸入操作的過濾器類。

class BusyAppFilter : public QObject 
{ 
protected: 
    bool eventFilter(QObject *obj, QEvent *event); 
}; 


bool BusyAppFilter::eventFilter(QObject *obj, QEvent *event) 
{ 
    switch (event->type()) 
    { 
    case QEvent::KeyPress: 
    case QEvent::KeyRelease: 
    case QEvent::MouseButtonPress: 
    case QEvent::MouseButtonDblClick: 
    case QEvent::MouseMove: 
    case QEvent::HoverEnter: 
    case QEvent::HoverLeave: 
    case QEvent::HoverMove: 
    case QEvent::DragEnter: 
    case QEvent::DragLeave: 
    case QEvent::DragMove: 
    case QEvent::Drop: 
     return true; 
    default: 
     return QObject::eventFilter(obj, event); 
    } 
} 

然後把這個代碼您的QApplication類:

QCursor busyCursor(Qt::WaitCursor); 
setOverrideCursor(busyCursor); 

BusyAppFilter filter; 
installEventFilter(&filter) ; 

//... do the process stuff ... 

removeEventFilter(&filter); 

restoreOverrideCursor(); 
+1

你應該使用'return false'而不是'return QObject :: eventFilter(obj,event);'。所有其他事件過濾器將自動調用。 – 2013-06-06 10:30:34