編集:根本的なパフォーマンスの問題は、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() メソッドを公開していません。プライベートな実装を掘り下げずに、どうすればこれを高速化できますか?