QAbstractItemModel:为什么在将大量项目插入模型时发出dataChanged并插入行信号这么慢?

时间:2012-02-07 10:21:50

标签: c++ xml qt qabstractitemmodel

嗨,请访问Stackoverflow中的所有Qt模型/视图编程大师。我正在处理的项目要求我为XML数据定义一个QAbstractItemModel派生模型。当我在执行此模型时遇到问题时,我之前曾在此问过一个问题: QSortFilterProxyModel crashes when deleting a row from the source model via the source model function

该模型目前在应用程序中的表现相当不错,除了一些我不知道如何解决的性能问题。其中一个功能 应用程序是通过设置Max Num和Rand数字来添加Frame元素xml节点。每个Frame元素都有Num和Rand编号,分别从0到MaxNum - 1和0到MaxRand-1。此外,我需要为Rand = 0 th和Rand = MaxRand-1 th元素添加子参数元素。缩略图如下:

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个Frame元素的总数。但是,当元素计数超过500左右时,通过QAbstractItemModel函数添加Frame元素变得痛苦且指数缓慢。 GUI冻结了很长一段时间,大部分时间都放弃了等待。

主要更新:

我在模型中插入大量1000个项目时发现导致速度减慢的原因。每插入一个项目,我都会调用insertRow(row,parent)和setData()一次,由于这些函数中发出的信号,这个结果非常昂贵。

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

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

1 个答案:

答案 0 :(得分:4)

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

void MyModel:setNewData(const QStringList newList) {

  beginResetModel();

  m_dataList = newList;

  endResetModel();
}

我认为这种方法也适用于您的情况。