c++ - 通过 QML 仿函数对 C++ 模型进行排序和过滤?

标签 c++ qt model qml filtering

我有一个多态(如任意角色)QObject 模型,它主要是从 QML 以声明方式实例化的,as in this answer ,并且我希望能够拥有自定义数据“ View ”,通过任意的和可能的 - 从代码字符串 JS 仿函数生成的运行时对模型进行排序和过滤,类似的东西:

  DataView {
    sourceModel: model
    filter: function(o) { return o.size > 3 }
    sort: function(a, b) { return a.size > b.size }
  }

QSortFilterProxyModel 接口(interface)似乎并不是特别适合这项任务,而是专注于静态角色和预编译规则。

我尝试在 C++ 端使用 QJSValue 属性,但似乎这是不可能的,C++ 代码无法使用该属性类型进行编译。如果我将属性类型设置为 QVariant,我会从 QML 收到错误消息,指出函数只能绑定(bind)到 var 属性。显然,varQVariant 的转换不会像返回值那样在此处启动。

最佳答案

正如您提到的,您可以使用 QJSValue。但这是相当静态的。如果你想使用像 filter: function(o) { return o.size > slider.value; 这样的过滤器怎么办? } 使用动态 slider ?您必须手动调用 invalidateFilter()

作为更实用的替代方法,您可以改用 QQmlScriptString作为属性(property) & QQmlExpression执行它。使用 QQmlExpression 允许您通过 setNotifyOnValueChanged 通知上下文更改.

你的语法会变成这样:filter: o.size > slider.value

如果您正在寻找开箱即用的解决方案,我已经在我的库中实现了它:SortFilterProxyModel on GitHub

可以看看ExpressionFilter & ExpressionSorter ,那些与您最初想要的相同。您可以在 repo 中查看完整的源代码。

使用方法:

import SortFilterProxyModel 0.2

// ...

SortFilterProxyModel {
    sourceModel: model
    filters: ExpressionFilter  { expression: model.size > 3 }
    sorters: ExpressionSorter { expression: modelLeft.size < modelRight.size }
}

但正如@dtech 提到的那样,为模型的每一行在 qml 和 c++ 之间来回切换的开销非常明显。这就是我创建更具体的过滤器和分类器的原因。在您的情况下,我们将使用 RangeFilterRoleSorter :

import SortFilterProxyModel 0.2

// ...

SortFilterProxyModel {
    sourceModel: model
    filters: RangeFilter  {
        roleName: "size"
        minimumValue > 3
        minimumInclusive: true
    }
    sorters: RoleSorter { roleName: "size" }
}

这样做,我们就有了一个很好的声明式 API,参数只从 qml 传递到 c++ 一次。然后,所有过滤和排序都完全在 C++ 端完成。

关于c++ - 通过 QML 仿函数对 C++ 模型进行排序和过滤?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50689617/

相关文章:

c++ - C C++ - TCP 套接字类 : Receive Problem

c++ - 是否可以捕获全局鼠标事件

c++ - cygwin gcc-6.4.0编译器

c++ - QObject::connection(const QObject *,const char *,const char *,Qt::ConnectionType)“无法将参数3从'fileProcessor'转换为const QObject *”

jquery - SimpleModal调整容器大小

ruby-on-rails - Rails 4 模型有效,但不会保存?

c# - 如何获取面板内单击事件的坐标?

c++ - Ghostscript api 请求 "press <return> to continue"

qt - 如何在 QML 中隐藏菜单项

python - Tensorflow:如何将卡住模型转换为保存模型