2012-12-05 133 views
4

正如文檔中明確指出的那樣,Qt GUI只能從主線程訪問。對於具有多個大表和繁忙表的複雜應用程序,這可能是Qt喜歡做的所有字體大小文本度量計算的瓶頸。我能想到的唯一選擇是使用不同流程的多任務處理。這些表格目前速度可以達到您可以獲得的速度,自定義模型直接映射到從另一個線程使用dataChanged()調用最緩慢的一組已更改的單元格調用的緩存。我已經對vTune進行了分析,70%的應用程序時間現在在Qt渲染代碼中。有什麼建議麼?多線程UI的最佳途徑?

+1

我最後一次處理的Qt(Qt的4.6左右),我喂大的模型(電子表格數據的幾十萬行)到QTableView中。我還注意到字體指標計算顯示在我的分析器輸出中。原來,['QHeaderView :: sectionSizeFromContents'](http://qt.gitorious.org/qt/qt/btbs/4.8/src/gui/itemviews/qheaderview.cpp#line2556)是罪魁禍首,它計算了行基於每個新行的字體的高度,即使所有行都具有相同的高度。我們用一個簡單的自定義標題視圖替換它,返回一個固定的高度 - 幫助了很多! –

+1

你嘗試過'setUniformRowHeights()'嗎?我不知道它是否會解決你的問題(它曾經爲我做過),我只是好奇。 – scai

+0

這些表格有多複雜? [QTableView具有批量大小屬性](http://doc.qt.digia.com/qt/qlistview.html#batchSize-prop),可以將視圖的更新設置爲限制模型的有限部分。也許你的表可以實現類似的東西? – Phlucious

回答

5

我沒有使用過QT,但是從幾乎所有我熟悉的GUI中,只從一個線程(GUI線程)訪問GUI是已知的問題。我爲這種情況使用了兩種解決方案,其中我更喜歡第一種:

1)您的表單將以計時器間隔更新GUI(本例中爲表格)。定時器在GUI線程的事件中被激活。在這些計時器事件中,您從全局變量中讀取數據並更新您的表格。全局變量可以根據您的意願更新任意多個線程。您可能需要同步(例如信號量)訪問全局變量。

2)在許多GUI的API線程可以通過分發GUI線程的功能(或對象),並要求它的ASAP執行它在它的上下文更新GUI。調用線程同時阻塞,直到GUI完成操作。我可以回想起來自Java和C#的InvokeInvokeLater,或wxPython的wx.CallAfter三個這樣的函數。

+0

+1:我在Linux上使用GTK +的技術#1,它工作得很好。如果可能的話,您肯定希望將非GUI任務分解爲單獨的線程,或者在GUI線程的「空閒處理程序」中執行它們。 –

2

如果您的表格條目和方法分幾步完成,您可以撥打QCoreApplication :: processEvents()來更新計算之間的qt ui。你可以做的另一件事是在不同的線程上運行一切,並在計算完成時從線程發出信號。最後,更新是在主線程的ui上完成的,但是是異步的。要連接到不同線程的信號,您必須使用qRegisterMetaType <>

3

使用MVC模式的一個變種,使模型多線程