【问题标题】:QSortFilterProxyModel filtering complete signalQSortFilterProxyModel 过滤完成信号
【发布时间】:2015-07-01 16:57:02
【问题描述】:

我正在使用自定义QSortFilterProxyModel 通过覆盖filterAcceptsRow() 来实现QTableView 的自定义过滤。当我更改过滤条件以及将filterAcceptsRow() 应用于整个表后,如何通知我的应用程序?

基本上,我想在应用过滤后获取可见项的列表,目前我通过在模型中实现的自定义函数计算此列表,该函数迭代行并获取可见行的列表。这是低效的,因为如果两次调用此函数之间没有发生过滤操作,将产生相同的结果。

【问题讨论】:

  • Qt MVC 并非设计用于处理可见项目的范围。模型不应该对视图一无所知。因为您可以将一个模型用于多个视图。
  • 我只需要过滤处理完成时的通知。
  • 没有这样的通知。因为排序是“即时”进行的。当您添加新项目时 - 会自动应用排序。
  • @SaZ。如果这是真的,视图如何知道模型更改后何时更新自己?
  • 有足够多的文档化方法,模型将如何通知视图有关更改。请阅读 qt 文档:doc.qt.io/qt-5/qabstractitemmodel.html(信号部分)

标签: python-3.x qt pyqt qtableview qsortfilterproxymodel


【解决方案1】:

所有模型在排序、过滤或以任何其他可能影响视图的方式更改之前和之后都应发出 layoutAboutToBeChanged()layoutChanged()

【讨论】:

  • 我之前的评论错了。我认为你是对的。投票赞成。上次,当我直接调用 layoutChanged 时,那里描述:stackoverflow.com/questions/16444558/…
  • QSortFilterProxyModel::invalidateFilter() 不发送。它早在invalidate() 时发送,但不是现在。
【解决方案2】:

根据我的观察(在 Qt 4.8 中),layout*() 信号将在对代理模型进行排序时触发,但在您实施过滤时不会触发。文档还明确引用了这些信号所表示的项目的顺序,过滤自然不会改变顺序,只会影响行。

在这种情况下,只有rows*(...) 信号(插入、移除等)会触发,具体取决于过滤器刚刚执行的操作。不利的一面是,如果过滤器是递归应用的(通常是这样),这些信号会大量触发,因此与单个结果动作相关联没有用。

要克服这个问题,您可以在设置过滤器后调用invalidate()(不是invalidateFilter,顺便说一句,因为它也不会触发布局信号)。

由于这重新应用了过滤排序(过滤时不需要后者,但无法避免),layout*()signals 将在两者都结束后触发。

但是最好自己处理过滤器字符串/regExp/whatever,而不是使用基本方法(如setFilterFixedString(...))来设置它们,以至少避免过滤两次 - 如果你已经没有太多开销重新实现了filterAcceptsRow(...)

另一种方法是在设置排序或过滤时发出自己的信号,并使用Qt::QueuedConnection 连接到它以确保它在过滤结束后执行。这就是我最终所做的(更新表的寄存器),据我所知,它按预期工作。

【讨论】:

  • 这似乎也是正在发生的事情。更改过滤器表达式时不会发出 layout*() 信号。
猜你喜欢
  • 2015-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多