如何有效地扩展 QTreeView 的整个子树?

Pau*_*ois 1 qt4 pyqt qtreeview

编辑:事实证明,根本性能问题是附加到 Expanded() 信号的尺寸适应函数,因此我将接受第一个答案并删除这个具有误导性的问题。

注意:我问这个问题是为了提供答案(也许会得到更好的答案)。该解决方案并不直观。

MacOS 版本的 Qt 可能有办法让用户扩展整个 QTreeView 子树(有一个未解决的错误),但非 MacOS 版本绝对没有。我正在尝试实现“按住 Shift 键并单击项目装饰可展开整个子树”的行为。

有两个问题。两者中较容易的一个是检测装饰上的 Shift 键单击。我通过拦截展开/折叠信号来做到这一点;他们检查 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
Run Code Online (Sandbox Code Playgroud)

这有点难看,但效果很好。

更难的问题是实现 _recursive_set_expanded(view, root, state)。递归崩溃非常快。然而,对索引的所有后代调用 view.setExpanded(True) 的明显实现非常非常慢——约 100 个索引需要花费数秒的时间。问题不在于昂贵的数据模型,因为 view.expandAll() 非常快。

一些源代码研究表明,expandAll() 所做的工作明显少于 Expand()。但是,Qt API 不公开 ExpandSubtree() 方法。如果不深入研究私有实现,如何才能快速实现这一点?

Ton*_*nyK 5

按“*”(星号)键展开节点的子节点,这正是您想要的。您是否尝试过使用假的“*”按键来调用 keyPressEvent?