编辑:事实证明,根本性能问题是附加到扩展()信号的大小匹配函数,所以我将接受第一个答案并删除这个问题,因为它具有误导性。
注意:我问这个问题是为了提供答案(也许会得到更好的答案)。解决方案并不直观。
Qt 的 MacOS 构建可能有一种方法让用户扩展整个 QTreeView 子树(它有一个开放的错误),但非 MacOS 构建绝对没有。我正在尝试实现“在项目装饰上的 shift-click 扩展整个子树”的行为。
有两个问题。两者中较容易的是检测装饰上的 shift-click。我通过拦截展开/折叠的信号来做到这一点;他们检查 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() 方法。如果不深入研究私有实现,如何才能快速做到这一点?