2012-02-07 112 views
1

嗨,所有Qt模型/視圖編程大師在這裏在Stackoverflow。我正在處理的項目需要我爲XML數據定義一個QAbstractItemModel派生模型。以前我曾問一個問題在這裏,當我實現這個模式的過程中遇到了一個問題: QSortFilterProxyModel crashes when deleting a row from the source model via the source model functionQAbstractItemModel:爲什麼發射dataChanged和插入行信號時,插入大量項目模型如此緩慢?

模型目前正在做的工作很好的應用,除了一些性能問題,我不知道如何解決。此 應用程序的功能之一是通過設置Max Num和Rand數字來添加Frame元素xml節點。每個Frame元素將有Num和Rand數字分別從0到MaxNum - 1和0到MaxRand-1。此外,我需要爲每個Rand = 0 th和Rand = MaxRand-1個元素添加一個子參數元素。縮寫的說明如下:

For Max Num=100, Max Rand=50 

<Frame Num="0" Rand="0"> 
    <Parameter Value="false"/> 
</Frame> 
<Frame Num="0" Rand="1"/> 
<Frame Num="0" Rand="2"/> 
... 
<Frame Num="0" Rand="48"/> 
<Frame Num="0" Rand="49"> 
    <Parameter Value="true"/> 
</Frame> 
<Frame Num="1" Rand="0"> 
    <Parameter Value="false"/> 
</Frame> 
<Frame Num="1" Rand="1"/> 
<Frame Num="1" Rand="2"/> 
... 
<Frame Num="1" Rand="48"/> 
<Frame Num="1" Rand="49"> 
    <Parameter Value="true"/> 
</Frame> 
... 
<Frame Num="99" Rand="0"> 
    <Parameter Value="false"/> 
</Frame> 
<Frame Num="99" Rand="1"/> 
<Frame Num="99" Rand="2"/> 
... 
<Frame Num="99" Rand="48"/> 
<Frame Num="99" Rand="49"> 
    <Parameter Value="true"/> 
</Frame> 

的應用工作得很好當兩個MaxNum來和MaxRand大約50。然而框架元件的小即總數,當元素計數超出500左右,幀的添加通過QAbstractItemModel函數的元素變得痛苦而指數級地變慢。 GUI長時間凍結,直到我放棄等待大部分時間。

重大更新:

我發現插入了大量的當是什麼原因造成的放緩,1000個說項目到我的模型。我插入的每個項目都調用了insertRow(row,parent)和setData()兩次,結果是由於這些函數內部發出的信號而非常昂貴。

我修改了insertRows(row,1000,parent)代碼,並定義了一個不發出dataChanged(currIndex,currIndex)的新silentSetData()。我還包括一個名爲notifyDataChanges(startRow,endRow,parentIndex)的新公共函數,該函數依次爲給定範圍的數據發出dataChanged信號。一切都很好,但現在調用者類將在插入整個數據集後顯式調用notifyDataChanges。

現在我想知道爲什麼發射dataChanged信號如此昂貴?有沒有人嘗試其他方法來克服這個問題時,一次插入/更改模型中的大量項目?

回答

4

另一種方法是顯式重置模型數據結構。例如,在我的一個模型中,數據用QStringList表示。我已經實現了一個重置​​模型中的數據的函數。例如:

void MyModel:setNewData(const QStringList newList) { 

    beginResetModel(); 

    m_dataList = newList; 

    endResetModel(); 
} 

我想象這種方法也適用於你的情況。

+0

我知道beginResetModel。我已經用它將XML文件初始加載到模型中。我的印象是重置模型不應該經常使用,因爲它重置所有附加的視圖,並可能減慢GUI,但似乎我錯了。 – ksming 2012-02-10 01:47:27

+0

根據您的建議,我添加了insertRows,setData和removeRows版本,它們不會發出任何dataChanged(),ratbi(),ratbr()或其他layoutChanged信號。然後我有調用類調用這些(我稱之爲)在開始和結束重置模型之間移除,插入和設置數據的無聲版本,以執行批量插入操作。速度顯着提高!我將在後面的回答帖子中將詳細信息發佈到我的解決方案中以供參考。無論如何,您的答案將被標記爲已接受。謝謝! – ksming 2012-02-10 09:49:04

+0

謝謝。我想象每次在大型數據集上調用'setData'時,事件系統都會充滿信號。 – Neox 2012-02-10 13:03:45