1

編集:根本的なパフォーマンスの問題は、expanded() シグナルに添付されたサイズに合わせた関数であることが判明したため、最初の回答を受け入れ、誤解を招く可能性があるため、この質問を削除します。

注:私はこの質問をしているので、答えを提供できます(そして、より良い答えが得られるかもしれません)。ソリューションは直感的ではありません。

Qt の MacOS ビルドには、ユーザーが QTreeView サブツリー全体を展開する方法がある場合があります (未解決のバグがありました) が、MacOS 以外のビルドには確実にありません。「アイテムの装飾をShiftキーを押しながらクリックすると、サブツリー全体が展開されます」という動作を実装しようとしています。

2 つの問題があります。2 つのうち簡単なのは、装飾のシフト クリックを検出することです。これは、展開/折りたたまれた信号を傍受することで行います。それらは、mousePressEvent によって設定された「グローバル」状態をチェックします。

# similar implementation for _on_expanded
@pyqtSlot(QModelIndex)
def _on_collapsed(self, index):
    if self._in_shift_press:
        self._in_shift_press = False
        _recursive_set_expanded(self, index, False)

def mousePressEvent(self, evt):
    # Make shift-click expand/collapse all
    if int(evt.modifiers() & Qt.ShiftModifier) != 0:
        self._in_shift_press = True
    try:
        QTreeView.mousePressEvent(self, evt)
    finally:
        self._in_shift_press = False

これは少し醜いですが、十分に機能します。

難しい問題は、_recursive_set_expanded(view, root, state) の実装です。再帰的な折りたたみは非常に高速です。ただし、インデックスのすべての子孫で view.setExpanded(True) を呼び出す明らかな実装は非常に遅く、最大 100 個のインデックスに対して数秒かかります。view.expandAll() は非常に高速であるため、問題は高価なデータ モデルではありません。

一部のソース ダイビングは、expandAll() が expand() よりもはるかに少ない作業であることを示しています。ただし、Qt API は expandSubtree() メソッドを公開していません。プライベートな実装を掘り下げずに、どうすればこれを高速化できますか?

4

4 に答える 4

4

「*」(アスタリスク) キーを押すと、ノードのサブノードが展開されます。偽の「*」キープレスで keyPressEvent を呼び出してみましたか?

于 2011-02-15T07:44:36.240 に答える
1

expandAll() は高速で、collapse(QModelIndex) も高速であるため、私の解決策は、これら 2 つのメソッドのみを使用し、expand(QModelIndex) の呼び出しを避けることです。

def _recursive_set_expanded(view, root, desired):
    """For |root| and all its descendents, set the 'expanded' state to |desired|.
    It is undefined whether expanded and collapsed signals are emitted."""
    state = {}
    def _recursive_get_state(view, model, index, under_root):
        if index == root:
            under_root = True
        num_children = model.rowCount(index)
        if num_children:
            if under_root:
                state[index] = desired
            else:
                state[index] = view.isExpanded(index)
            for i in xrange(model.rowCount(index)):
                _recursive_get_state(view, model, model.index(i,0, index), under_root)

    _recursive_get_state(view, view.model(), QModelIndex(), False)
    view.expandAll()
    for k,v in state.iteritems():
        if not v:
            view.setExpanded(k, False)
于 2011-02-15T03:07:39.957 に答える
0
void MainWindow::expandNode(const QModelIndex &parentIndex, bool expand) {
  tree->setExpanded(parentIndex, expand);
  for (qint32 rowNum = 0; rowNum < treeModel->rowCount(parentIndex); ++rowNum) {
    QModelIndex childIndex = treeModel->index(rowNum, 0, parentIndex);
    tree->setExpanded(childIndex, expand);
    expandNode(childIndex);
  }
}
于 2014-04-12T13:20:19.267 に答える