如何有效地扩展 QTreeView 的整个子树? [英] How can I efficiently expand an entire subtree of a QTreeView?

查看:38
本文介绍了如何有效地扩展 QTreeView 的整个子树?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

事实证明,根本性能问题是附加到 expand() 信号的适合大小的函数,所以我将接受第一个答案并删除这个具有误导性的问题.

it turns out that the root performance problem was a size-to-fit function attached to the expanded() signal, so I'm going to accept the first answer and delete this question for being misleading.

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

Note: I'm asking this question so I can provide an answer for it (and maybe get a better answer). The solution is not intuitive.

Qt 的 MacOS 构建可能有一种方法让用户扩展整个 QTreeView 子树(有一个开放的错误),但非 MacOS 构建绝对没有.我正在尝试实现按住 Shift 键单击项目装饰扩展整个子树"的行为.

MacOS builds of Qt may have a way for the user to expand an entire QTreeView subtree (there was an open bug for it) but non-MacOS builds definitely do not. I am trying to implement the behavior "shift-click on the item decoration expands the entire subtree".

有两个问题.两者中较容易的是检测装饰上的移位点击.我通过拦截展开/折叠的信号来做到这一点;他们检查 mousePressEvent 设置的一些全局"状态:

There are two problems. The easier of the two is detecting a shift-click on the decoration. I do this by intercepting the expanded/collapsed signals; they check some "global" state set up by the 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

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

This is a little ugly, but it works well enough.

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

The harder problem is implementing _recursive_set_expanded(view, root, state). A recursive collapse is very quick. However, the obvious implementation of calling view.setExpanded(True) on all descendents of an index is very very slow -- multiple seconds for ~100 indices. The problem is not an expensive data model, since view.expandAll() is very fast.

一些源代码分析表明,expandAll() 的工作量明显少于 expand().但是,Qt API 没有公开 expandSubtree() 方法.在不深入研究私有实现的情况下,如何快速实现这一点?

Some source diving shows that expandAll() does significantly less work than expand(). However, the Qt API doesn't expose an expandSubtree() method. How can this be made fast, short of digging into the private implementation?

推荐答案

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

Pressing the '*' (asterisk) key expands a node's subnodes, which is just what you want. Have you tried calling keyPressEvent with a fake '*' keypress?

这篇关于如何有效地扩展 QTreeView 的整个子树?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆