1

StackoverflowのすべてのQtモデル/ビュープログラミングの達人にこんにちは。私が取り組んでいるプロジェクトでは、XMLデータのQAbstractItemModelから派生したモデルを定義する必要があります。このモデルの実装中に問題が発生したときに、以前にここで質問をしました 。ソースモデル関数を介してソースモデルから行を削除すると、QSortFilterProxyModelがクラッシュします。

モデルは現在、解決方法がわからないいくつかのパフォーマンスの問題を除いて、アプリケーションでかなりうまく機能しています。このアプリケーションの機能の1つは、最大数とランド数を設定することにより、フレーム要素のxmlノードを追加することです。各Frame要素には、それぞれ0からMaxNum-1および0からMaxRand-1までのNum番号とRand番号の両方があります。さらに、Rand=0番目と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の両方が小さい場合、つまりFrame要素の総数が約50の場合、アプリケーションは正常に機能します。ただし、要素数が500程度を超えると、QAbstractItemModel関数を介したFrame要素の追加が非常に遅くなります。GUIが長時間フリーズし、ほとんどの時間待つことを諦めました。

メジャーアップデート:

モデルに1000個のアイテムを大量に挿入すると、速度が低下する原因がわかりました。挿入されたアイテムごとに1回insertRow(row、parent)とsetData()の両方を呼び出していましたが、これらの関数内で発行されるシグナルのために非常にコストがかかることがわかりました。

代わりに、コードをinsertRows(row、1000、parent)に変更し、dataChanged(currIndex、currIndex)を発行しない新しいsilentSetData()を定義しました。また、notifyDataChanges(startRow、endRow、parentIndex)と呼ばれる新しいパブリック関数も含めました。この関数は、指定された範囲のデータに対してdataChangedシグナルを1回発行します。すべて問題ありませんが、データセット全体が挿入された後、呼び出し元クラスはnotifyDataChangesを明示的に呼び出す必要があります。

今、私はなぜdataChangedシグナルをそれほど高価なのか疑問に思っていますか?モデルに多数のアイテムを一度に挿入/変更するときに、この問題を解決するために他の手段を試した人はいますか?

4

1 に答える 1

4

これを行う別の方法は、モデルのデータ構造を明示的にリセットすることです。たとえば、私のモデルの1つでは、データは。で表されますQStringList。モデル内のデータをリセットする関数を実装しました。例えば:

void MyModel:setNewData(const QStringList newList) {

  beginResetModel();

  m_dataList = newList;

  endResetModel();
}

このアプローチはあなたの場合にも当てはまると思います。

于 2012-02-09T12:18:02.253 に答える