2009-09-06 12 views
23

我的程序的main(main main函數)線程保留用於非GUI任務。它調用了很多冗長的計算函數。所有實施的GUI都在單獨的線程中完成他們的工作。如何在主線程忙時使Qt工作?

我現在要使用Qt實現一個更多的GUI。 Qt documentation說所有GUI相關的任務都應該在主線程中完成。 在我的情況下,偶爾在主線程中插入QCoreApplication :: processEvents()調用實際上是無用的,因爲它們之間有很大的延遲。

有什麼辦法可以克服Qt的這個限制嗎? 在Qt程序的主線程中不可能做一些與非GUI相關的東西嗎?

+4

爲什麼你不能在另一個線程上工作? – Kornel

+1

只是因爲歷史原因。重構將是一個痛苦,所以我考慮做一些研究,如果它是可以避免的。 – Basilevs

回答

20

不,你應該在一個單獨的線程中做你的計算。正如你已經提到過的,在QCoreApplication::processEvents()中有一個解決方法,但它聽起來像你無法爲你工作。

如果您不想完成設置QThread和移動所有代碼的所有工作,您可能會發現QtConcurrent::run函數非常有用 - 它允許您異步運行函數。

幾點提示:您應該儘量保持主線(GUI)儘可能輕。大量的IO或計算應該使用QtConcurrent :: run異步完成,或者在單獨的QThread中運行。根據代碼的複雜程度,您可能會忽略QtConcurrent方法。

+1

我沒有看到使用QtConcurrent :: run()而不是QThread的巨大優勢。這實際上是更多的工作。堅持與QThread,它很容易實現 –

+2

這取決於你在做什麼以及你的程序是如何構建的。如果你需要一個永久運行的永久線程,那麼使用QThread。如果您需要運行很多小型(通常是獨立的)任務,並且您不關心哪些是在什麼時間運行,那麼請使用Q​​tConcurrent。 – Thomi

+0

是的,我同意我可能對它有點困難......就像你說這取決於你需要什麼。 –

4

最好將長計算卸載到其他線程上,以便主GUI線程保持響應。老派的單處理方式是確保你的計算永遠不會運行太久而沒有輪詢GUI事件處理程序,但是這不會擴展到多核。

幸運的是Qt擁有出色的threading support。在過去,你就得滾你,自己的系統,例如使用QThreadQMutexQWaitCondition等外包出去的任務的線程池,但最近發佈的Qt做出事情變得更容易與更高級別的抽象,如QThreadPoolQtConcurrent::runQFuture

+1

爲什麼不使用線程之間的QObject連接? –

0

我不知道如果你從另一個線程調用QApplication :: exec(),那麼它會變成你的GUI線程。只是一個想法。

(讓我們知道它是否有效,這將是有趣的...)

+0

你爲什麼要這麼做?如果你需要做的工作吐出你的代碼,並在不同的線程上運行它的一半,你可以做得很好......或者我錯過了什麼? – Thomi

+0

我不推薦,我只是給出一個小貼士,說明如何實現OP所要求的內容。原因可能是其他庫需要在主線程中完成任務。 (IIRC,OpenSG 1.x需要在同一個線程中完成渲染和加載,所以我們在主線程中結束了沉重的OpenGL繪圖(因爲我們在該線程中加載了所有圖形)。 ,但它就是這麼做的(它在2.x中是固定的,IIRC) – Macke

+1

你可以做到這一點,我們只是通過一個簡單的應用程序來完成它,但是當程序關閉時,我們得到一個無效的free()錯誤或double free()錯誤 – dgrant

相關問題