2013-04-22 15 views
5

我在Qt中有一個UI應用程序,我有幾個運行大規模SQL查詢返回數千個結果的函數。Qt程序掛起(不響應)直到函數結束然後再次開始工作

當運行此查詢的按鈕被點擊時,UI窗口只是立即轉到'沒有響應',但是我可以從控制檯輸出中看到一切仍然在後臺運行。一旦函數結束,數據按預期呈現並且UI再次響應並且功能完全正常。

我知道這是因爲這個函數由於大量的結果而循環數千次,但是我希望我可以放入一個加載欄,它隨着搜索的進行而不是隻是鎖定了窗口,看起來程序崩潰了。 AFAIK我沒有記憶韭菜,所以有沒有人有任何建議?

哦也即時通訊想着它不是內存韭菜,因爲當我點擊該按鈕,任務管理器顯示只用於此過程一對夫婦MB的內存和處理器是絕不杏要麼

+8

您應該閱讀有關_threading_。 – 2013-04-22 14:29:52

+0

請熟悉'threading' ... – 2013-04-22 14:30:22

+2

此外,只需放置一個進度條是沒有用的,因爲驅動GUI的整個事件循環在您運行函數時不會運行。有了Qt,在做一些可能需要很長時間的事情時纔可以啓動一個工作線程。工作者線程可以輕鬆地將信號發送到GUI以更新進度條。 – 2013-04-22 14:35:08

回答

3

在應用程序中,有一個線程負責處理用戶界面事件,消息,無論你想調用它們。假設你有一個按鈕點擊事件。只要不從回調函數返回,就不會觸發其他UI事件(重繪,更新等),並且UI變得無響應。

爲了緩解這種情況,您應該考慮在單獨的線程中執行耗時的任務,一旦完成後,請相應地更新UI。如果您在處理任務時需要阻止用戶界面,則可以禁用控件,顯示彈出進度欄等,但請保持UI線程相對空閒以避免「無響應」問題。

+0

由於生病了看線程,我認爲這不會是一些巨大的代碼重寫,並可以很容易地被合併? – AngryDuck 2013-04-22 14:39:02

+0

@AngryDuck,閱讀[Threading Basics](http://qt-project.org/doc/qt-4.8/thread-basics.html) – Paul 2013-04-22 15:38:26

+0

我得到了線程的主體,但文檔是如此不完整,我實際上不知道如何併入它 – AngryDuck 2013-04-22 15:39:40

5

比使用線程更簡單的解決方案是使用QCoreApplication::processEvents()。如果你的代碼是這樣的:

void slowFunction() 
{ 
    lostOfResults = makeSqlQuery(...); // quite fast 
    for (r in lostOfResults) 
     doSomethingWithResult(r); // one call is quite fast 
} 

如果一個SQL查詢或一個doSomethingWithResult()並不需要太多的時間,你可以處理未決使用QCoreApplication :: processEvents()這樣的事件:

void slowFunction() 
{ 
    lostOfResults = makeSqlQuery(...); 
    for (r in lostOfResults) 
    { 
     doSomethingWithResult(r); 
     QCoreApplication::processEvents(); 
    } 
} 

現在處理GUI事件並且程序不凍結。但是,如果單獨的SQL查詢需要很長時間(幾秒鐘),這無濟於事。那麼你應該考慮單獨的線程。

相關問題