2

を使用しQAbstractItemModelて、ツリー モデル (数個のハウンド アイテムまで) を表します。データ自体は動的であり、いつでもノードが表示または非表示になり、値 (または他の役割) が変更される可能性があります。

モデルを変更するのは簡単です。QTreeView に変更を通知するために信号を効率的に送信する方法を知りたいです (ほとんどのノードは折りたたまれています)。

任意の時点で、複数の変更が同時に発生する可能性があります (行の挿入および/または削除)。

  1. beginInsertRows/ endInsertRows/ beginRemoveRows/を使用しendRemoveRowsて、ビューに複数の変更を通知する方法はありませんか?
  2. パフォーマンスに関して、最良の戦略は何でしょうか? たとえば、リーフからルートまで / 各ノードについて - 下から上 (vs 上から下) / 挿入前の削除 / など。
  3. beginResetModel/endResetModel必然的に効率が低下しますか?
  4. を使用する利点はありますQStandardItemModelか? (この特定のケースの場合)。
4

1 に答える 1

3
  1. はい。ばらばらな削除/追加を全員に通知する方法は、複数のシグナルを送信することです。ほとんどの場合、親インデックスと行/列インデックスの区切りだけでなく、複雑なデータ構造を渡すためのオーバーヘッドが増加します。

  2. ルートに近いアイテムの削除/追加についてのみ通知する必要があります。親がその後姿を消した場合、子の削除について通知しても意味がありません。親に関する通知は、明らかに、子がもう存在しないことを意味します。

  3. 効率だけでなく、状態も重要です。モデルをリセットすると、ビュー ステートがリセットされます。ビューは、リセットを受け取ると、まったく新しい無関係なモデルを取得したと想定せざるを得ません。そのため、選択、展開/折りたたみ状態などが失われます。ビューが他の方法で動作する方法はありませんリセットします。そうしないと、ビューがモデルのコンテンツの独自のコピーを保持する必要があります。

    モデルのリセットはすべてのアイテムの再レイアウトを意味し、非常にコストがかかる可能性があるため、元のアイテムの合計で 50% 以上が変更 (削除/置換/追加) された場合にのみ実行する必要があります。 .

  4. いいえ、利点はありません。データをバリアントとして保存しない限り、使用QStandardItemModelすると常にメモリ オーバーヘッドが大きくなります。これは、ニーズに正確に適合する場合に意味のある便利なクラスです。実は使い方に気をつけないと効きが悪くなるのです。

    たとえば、深さ優先を反復し、最も遠い子を最初に削除してアイテムを削除する場合、QStandardItemModelは未来を予測できません。つまり、それらすべての子の共通の祖先を本当に削除したいのに、不必要に多くの変更イベント。独自のモデルで適切に処理できます。または、子に触れずに共通の親を単純に削除すると、それらも暗黙的に削除されるためです。

于 2014-02-11T18:54:01.180 に答える