2014-01-15 60 views
1

我正在研究一個programm(notifyfs),它負責緩存目錄條目並觀察底層文件系統的變化。緩存存儲在共享內存中,(gui)客戶端可以非常輕鬆地使用緩存。使用QTreeView和QStandardItemModel的應用程序沒有趕上

服務器(notifyfs)和客戶端之間的通信可以使用套接字或通過共享內存本身,通過共享互斥鎖和條件變量。

當客戶端想要加載目錄時,它執行以下操作:

a。選擇一個「視圖」,這是共享內存中的一個數據結構,它由共享互斥量,條件變量和小隊列(數組)組成,以便與客戶端通信添加/刪除/更改事件。

b。客戶端使用它已經在共享內存中找到的內容填充他/她的模型

c。通過引用視圖向服務器發送消息,並向其加載其內容的路徑指示。這可能是一條路徑,但如果可能的話,父項。 d)。服務器收到消息(進行一些檢查),在目錄上設置一個監視,並同步該目錄。當目錄尚未進入緩存時,這意味着它檢測到的每個條目都存儲在緩存中。在這樣做的時候,它表示視圖(共享內存中的數據)添加了一個條目,並將該事件存儲在數組/隊列中。

e。 gui客戶端有一個特殊的線程在共享內存中不斷觀察這個視圖,以便使用pthread_cond_wait調用進行更改。這個線程是一個特殊的io線程,它可以發送三個信號:添加條目,刪除條目和改變條目。它從數組隊列中讀取的正確參數:對條目的引用以及操作是什麼。這三個信號連接到我的模型中的三個插槽,該插槽基於QStandardItemModel。

這個效果很好。速度非常快。測試時,我有很多調試輸出。刪除這些測試它沒有這個額外的緩慢的io,它看起來像QTreeView無法趕上變化。當加載一個目錄時,它會加載三分之二的目錄,而當加載另一個目錄時,這個目錄會越來越少。

我已經使用Qt :: QueuedConnection將特殊線程的不同信號連接到模型。

使用insertRow(row,list)調用來完成在某一行添加一行,其中row當然是行,list是項目的QList。

我一直在尋找這個問題一段時間,看到所有的變化都被特殊的io線程檢測到,並且信號被模型接收。以某種方式只收到QTreeView的信號。我一直在想,我是否必須將模型信號和treeview的接收槽之間的通信也設置爲「Qt :: QueuedConnection」?也許別的東西?

+0

你的問題太沉重。你可以簡化它:「有時QTreeView不會更新,即使新項目被添加到模塊中,如何解決它?」並提供最少的代碼示例來重現您的問題。在大多數情況下,這些錯誤出現在不正確的模型實現之後。我可以添加一個代碼示例,顯示如何在從分離的線程掃描文件夾期間使用文件列表填充QTreeView。 –

+0

你的意思是太重?太多細節?我的問題有一些細節,因爲我想在問題發生時提供信息,以及我已經做了什麼來阻止我已經嘗試過的建議。你的想法提出一個像「有時QTreeView不更新」這樣的問題太短了。然後人們會自然而然地提出更多細節。 – user1388973

+1

@ user1388973:有時候一些自包含的代碼比一千個詞更好。 –

回答

0

在反應中提出的是將模型放入特殊線程中。這很誘人,但不是解決這個問題的正確方法。模型和視圖應該在同一個線程中。

我通過儘可能多地解決這個問題,當涉及到通過特殊的io線程提供數據的模型。我移動了一些函數,將模型填充到這個特殊的io中,並使用標準調用來插入或刪除一行。這工作。

感謝大家給予的建議,

燕姿苯教

相關問題