2012-10-03 218 views
4

有沒有一種安全的方式來使用Qt而不調用QApplication :: exec()?有沒有辦法在沒有QApplication :: exec()的情況下使用Qt?

我有很多不同的對象在多個資源(至少其中一個正在與Web應用程序服務器通信)上執行長壽命進程。我正在製作一個GUI應用程序,提示用戶在正確的時間輸入這些不同的進程。我希望在一個地方有我的'流'邏輯 - 確定下一步要做什麼的邏輯,而不是像對話類那樣的GUI對象。我在想我可以這樣做:

... 

wait_dialog dlg; 
dlg.setModal(false); 
dlg.show(); // Should return... 

netobject.start_long_lived_process_that_happens_on_other_thread(&completion_callback); 
while (!completion_callback_called()) 
{ 
    qApp->processEvents(); 
    netobject.pump_callbacks(); 
    magically_avoid_busywait_while_still_servicing_qt_somehow(); 
} 

dlg.hide(); 

... 

從Qt的角度來看,這是安全嗎?實施magically_avoid_busywait_while_still_servicing_qt_somehow()有沒有「好」的方法?

我想在這裏完成的是以最明確的方式編寫我們的處理流程。我想一個單一的功能,這是否:

show_a_non_modal_wait_dialog() 

start_some_processing_1() 

wait_for_processing_1_to_finish() 

dismiss_non_modal_wait_dialog() 

show_modal_input_dialog() 

if (cancelled) return 

show_a_non_modal_wait_dialog() 

start_some_processing_2() 

wait_for_processing_2_to_finish() 

dismiss_non_modal_wait_dialog() 

show_modal_input_dialog() 

if (cancelled) return 

... 

我真的想避免是蹬掉,並等待Qt控件和窗口內的處理。另外,處理對象本身完全獨立於Qt。我想我正在嘗試做的是用一個輔助回調和狀態變量在一個函數中創建一個控制器。

+0

我想我不知道爲什麼你需要暫停事件處理。我相信設置爲0毫秒的QTimer會在gui有機會時運行,並且可以用來從其他線程收集信號以在gui線程上運行代碼並避免任何線程死亡。所以你是線程對象(QThread)可以處理它的業務,並在需要輸入時發出信號,然後停止自己。 gui線程捕獲該信號,提示用戶,給線程結果。然後該線程可以繼續。或者我誤解了? – Thadeux

+0

我們的應用程序在Qt-bits和我們其他應用程序之間有明確的分界線。我們的大多數源文件(包括上面的主函數)都沒有通過moc工具運行,也不能發送或接收Qt信號。 –

+0

儘管掛起QApplication的空閒時間可能會執行此功能,但這意味着該功能必須重新輸入,並且會成爲一個醜陋的狀態機器。我所希望的是一個可以從頭到尾運行的單一功能 - 這將使程序流程非常明確。 –

回答

5

你想要的是一個事件循環,也就是應用程序的主事件循環。這可以通過使用QEventLoop來完成:

wait_dialog dlg; 
dlg.setModal(false); 
dlg.show(); // Should return... 

QEventLoop loop; 
connect(&netobject, SIGNAL(done()), &loop, SLOT(quit())); 
netobject.start_long_lived_process_that_happens_on_other_thread(); 

loop.exec(); // BLOCKING (non-busy) until quit() is called via the signal done() 

雖然這是(在我眼裏)乾淨的代碼,這需要你的netobject類是一個QObject和實施的信號done()(這也是不是提供回調清潔劑)。

現在,您可以將這整個代碼包裝在一個函數中,這個函數本身就是一個阻塞調用,所以如果需要的話,它可以從對話框中返回一些結果。

+0

啊,既然你擴展了關於該對象不是Qt相關信息的問題,我想補充一點,你也可以創建一個回調方法,只是退出一個特定的QEventLoop而不是做這個連接。這基本上是一樣的。 – leemes

+0

我打算把這個標記爲'答案'。我喜歡它完全避免了processEvents()這似乎有點狡猾,似乎有一些我不明白的危險異常(如DeferredDelete事件?)。 –

+0

你不知道這對我有多大幫助! – Luca

相關問題