QAbstractItemModel:为什么在模型中插入大量项目时发出dataChanged和insert行信号如此缓慢



欢迎Stackoverflow中的所有Qt模型/视图编程大师。我正在进行的项目要求我为XML数据定义一个QAbstractItemModel派生模型。我之前在这里问过一个问题,当我在实现这个模型时遇到了一个问题:QSortFilterProxyModel在通过源模型函数从源模型中删除行时崩溃

该模型目前在应用程序中做得很好,除了一些我不知道如何解决的性能问题。其中一个函数应用程序是通过设置"最大数量"one_answers"随机数"来添加Frame元素xml节点。每个Frame元素的Num和Rand数字分别从0到MaxNum-1和0到MaxRand-1。此外,我将需要为Rand=0和Rand=MaxRand-1的每个元素添加一个子Parameter元素。缩写图示如下:

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都很小时,即Frame元素的总数约为50时,应用程序工作良好。然而,当元素计数超过500左右时,通过QAbstractItemModel函数添加Frame元素的速度会变得非常缓慢。GUI冻结了很长一段时间,以至于我放弃了大部分时间的等待。

主要更新:

当我在模型中插入大量(比如1000个)项目时,我已经发现了导致速度减慢的原因。我为每个插入的项调用insertRow(row,parent)和setData()一次,由于这些函数内部发出的信号,这是非常昂贵的。

我已经将代码修改为insertRows(row,1000,parent),并定义了一个新的silentSetData(),它不发出dataChanged(currIndex,currIndex)。我还包含了一个新的公共函数notifyDataChanges(startRow、endRow、parentIndex),它依次为给定的数据范围发出一次dataChanged信号。一切都很好,但现在调用程序类需要在插入整个数据集后显式调用notifyDataChanges。

现在我想知道为什么发射dataChanged信号如此昂贵?当一次在模型中插入/更改大量项目时,是否有人尝试过其他方法来克服这个问题?

另一种方法是显式重置模型数据结构。例如,在我的一个模型中,数据用QStringList表示。我已经实现了一个重置模型中数据的功能。例如:

void MyModel:setNewData(const QStringList newList) {
  beginResetModel();
  m_dataList = newList;
  endResetModel();
}

我想这种方法也适用于你的情况。

最新更新