如何使用QSortFilterProxyModel来过滤只显示子节点及其父节点的树模型

How to use QSortFilterProxyModel to filter a tree model that only display children nodes with their parents?

本文关键字:父节点 模型 子节点 显示 QSortFilterProxyModel 何使用 过滤      更新时间:2023-10-16

我有一个从QAbstractItemModel派生的工作树模型,我希望使用QSortFilterProxyModel子类来过滤它,以仅显示某些标准的子节点。例如,我有以下树:

A
- B
-- C1
-- C1
-- C1
--- C2
- D
- E

我想用节点名称== C1的条件来过滤这个树,并且只显示具有C1的节点及其子节点,如下所示:

C1
C1
C1
- C2

我已经有一个子类与filterAcceptsRow()重新实现,可以部分做我想要的,但它仍然会显示C1节点的父节点和祖父节点:

A
- B
-- C1
-- C1
-- C1
--- C2

我认为这是因为要考虑子节点,它们的父节点必须通过filterAcceptsRow()测试,我对吗?我如何实现filterAcceptRows()或其他方法,这样它就可以做我所描述的?

我曾经在qtcenter和qtforum问过这个问题,但是没有得到任何有用的回复。我试图直接使用beginMoveRows和endMoveRows在filterAcceptsRow()内移动QSortFilterProxyModel子类的索引,但这只是由于危险的const_cast而导致测试应用程序崩溃。

好了,我找到解决问题的办法了。只需使用QTreeView::setRootIndex()将索引B作为输入参数。索引B成为QTreeView的根索引,它是隐藏的,只有它的子索引才完整显示。

找到这个解决方案后,我觉得自己真笨。我猜我太专注于使用代理模型来修改数据的呈现方式,我完全忘记了QTreeView。

我不认为这是可能实现使用QSortFilterProxyModel。这样做的原因是这个类只过滤元素——也就是说,它会根据给定的标准隐藏(或不隐藏)某些元素。您要做的是将树重组为新的树(从根子节点的任意位置选择元素)。这只能通过创建自己的QProxyModel后代并实现自己的树重建,以及在旧树和新树之间映射索引来实现。

在这里详细描述如何做到这一点有点长。

当然setRootIndex是这种情况下的解决方案,但如果您将寻找更复杂的模型操作,您可以考虑使用自定义代理模型,如http://lynxline.com/category/models/