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++ - 为什么 'this' 指针在单步执行代码时会更改其值?

c++ - QML 与 Qt for Embedded System 在 uclinux 上一起运行吗?

php - Laravel - 访问模型属性的不同方法

cakephp:如何在模型中使用 find 语句而不是 Controller

c++ - 过载 - 不在范围内

c++ - Boost asio C++ 20 协程 : co_spawn a coroutine with a by-reference parameter unexpected result

c++ - cmake 类似于 qmake 字符串文字

c++ - 使用 QAudioRecorder 时禁止创建 wav 文件

view - Aurelia - 直通路线