我正在使用自定义QSortFilterProxyModel
通过覆盖QTableView
来为filterAcceptsRow()
实施自定义过滤。如何在更改过滤条件时以及在整个表格中应用filterAcceptsRow()
后通知我的应用程序?
基本上,我希望在应用过滤后获得可见项目的列表,目前我通过我在模型中实现的自定义函数计算此列表,该函数迭代行并获得可见行列表。这是低效的,因为如果在两者之间没有发生过滤操作,则对此函数的两次调用将产生相同的结果。
答案 0 :(得分:5)
所有模型应在排序,过滤或以可能影响视图的任何其他方式进行排序,过滤或更改之前和之后发出layoutAboutToBeChanged()
和layoutChanged()
。
答案 1 :(得分:5)
根据我的观察(在Qt 4.8中),layout*()
信号将在排序代理模型时触发,但如果实施过滤则不会。文档也明确引用这些信号所指的项目的顺序,过滤自然不会改变顺序,只影响行。
在这种情况下,只有rows*(...)
信号(插入,移除等)才会触发,具体取决于过滤器的功能。不利的一面是,如果过滤器是递归应用的(通常是这样的话),这些信号将以质量为单位发射,因此对于单个结果动作没有用处。
要克服此问题,您可以在设置过滤器后调用invalidate()(不是invalidateFilter btw,因为它也不会触发布局信号。)
因为这会重新应用过滤和排序(后者在过滤时不需要,但无法避免),layout*()
信号将在两者结束后触发
然后最好自己处理过滤字符串/ regExp /,而不是使用基本方法(如setFilterFixedString(...)
)来设置它们,至少避免过滤两次 - 如果没有多少开销,如果您已经重新实施了filterAcceptsRow(...)
。
另一种方法是在设置排序或过滤时发出自己的信号,并使用Qt::QueuedConnection
连接到它,以确保在过滤完成后执行它。这就是我最终做的(更新表的注册表),并且我可以告诉它的工作方式与预期的一样。