Qt ProxyModel性能问题

Qt ProxyModel性能问题,qt,c++11,qt5,Qt,C++11,Qt5,因此,我有一个带有QTreeView的Qt应用程序,它有一个自定义模型(源自qabstractemmodel)和一个用于过滤的自定义模型代理(源自QSortFilterProxyModel)。或多或少简单(有点类似于),在功能方面工作良好 该视图显示具有键值对的两列树。键很少更新,但值经常更新(很多条目每秒更新几次)。在代理模型中,我重载filterAcceptsRow以基于键定义可见性。但是每一次值的更改都会发出一个dataChanged信号,导致视图再次调用代理(filterAcceptsR

因此,我有一个带有
QTreeView
的Qt应用程序,它有一个自定义模型(源自
qabstractemmodel
)和一个用于过滤的自定义模型代理(源自
QSortFilterProxyModel
)。或多或少简单(有点类似于),在功能方面工作良好

该视图显示具有键值对的两列树。键很少更新,但值经常更新(很多条目每秒更新几次)。在代理模型中,我重载
filterAcceptsRow
以基于键定义可见性。但是每一次值的更改都会发出一个
dataChanged
信号,导致视图再次调用代理(
filterAcceptsRow
),并且该调用的代价有些高(对元素及其子元素的正则表达式进行评估)。通过缓存所有计算,
filterAcceptsRow
中有一些优化空间,但最好限制对该函数的调用。是否可以限制哪些列触发对代理的调用

你有什么建议给我吗


编辑:谢谢你的输入。我不知道
dynamicSortFilter
。我禁用了动态排序,还连接了来自模型的
dataChanged
-信号,以查看键列是否已更改,并在这种情况下称为invalidate。这就解决了它。

我也遇到了同样的问题,通过从代理模型本身而不是从主模型发出
dataChanged
信号来解决它。或者,您可以禁用动态排序/筛选(
dynamicSortFilter
property),并在需要筛选或排序时手动调用它


另外,我不确定,但可能只需在
dataChanged
信号中指定列就可以了。

我也遇到了同样的问题,通过从代理模型本身而不是从主模型发出
dataChanged
信号来解决。或者,您可以禁用动态排序/筛选(
dynamicSortFilter
property),并在需要筛选或排序时手动调用它


另外,我也不确定,但可能只需在
dataChanged
信号中指定列就可以了。

如果您查看代码,您会发现大多数工作仅在启用
dynamicSortFilter
时完成。我想你的代码就是这样


没有它你能活吗?可能每100次更新或每秒调用一次
invalidate()
,具体取决于最先发生的更新。

如果查看代码,您会发现大多数工作仅在启用
dynamicSortFilter
时完成。我想你的代码就是这样


没有它你能活吗?可能每100次更新或每秒调用一次
invalidate()
,具体取决于最先发生的更新。

因此,总结一下:您不希望每次数据更改都会导致模型重新过滤吗?那么,您希望如何触发过滤?无论如何,我会深入研究Qt源代码,找到实际调用
filterAcceptsRow
的位置,看看代码中是否有任何东西可以帮助您。我不这么认为,因为
filterAcceptsRow
可以任意定义,包括查看其他行。我认为您需要更改
QSortFilterProxyModel
本身的代码。如果您的代码是/可以是GPL,或者您拥有商用Qt许可证,那么您只需将
QSortFilterProxyModel
的代码复制到您的应用程序代码中,并对其进行修改即可。如果您决定这样做,请确保您理解这两种情况下的许可含义。另一种方法是自己从头开始实现等价于
QSortFilterProxyModel
。@hyde它应该由对键列的更改触发。因此,总结一下:您不希望每次数据更改都导致模型被重新筛选?那么,您希望如何触发过滤?无论如何,我会深入研究Qt源代码,找到实际调用
filterAcceptsRow
的位置,看看代码中是否有任何东西可以帮助您。我不这么认为,因为
filterAcceptsRow
可以任意定义,包括查看其他行。我认为您需要更改
QSortFilterProxyModel
本身的代码。如果您的代码是/可以是GPL,或者您拥有商用Qt许可证,那么您只需将
QSortFilterProxyModel
的代码复制到您的应用程序代码中,并对其进行修改即可。如果您决定这样做,请确保您理解这两种情况下的许可含义。另一种方法是自己从头开始实现相当于
QSortFilterProxyModel
(任务可能不会太大)。@hyde它应该通过更改键列来触发。