dte*_*ech 5 c++ qt filtering model qml
我有一个多态(如任意角色)QObject模型,该模型主要是从 QML 中以声明方式实例化的,如本答案中所示,并且我希望能够拥有自定义数据“视图”,通过任意方式对模型进行排序和过滤,并且可能 -从代码字符串 JS 函子生成的运行时,类似这样:
DataView {
sourceModel: model
filter: function(o) { return o.size > 3 }
sort: function(a, b) { return a.size > b.size }
}
Run Code Online (Sandbox Code Playgroud)
该QSortFilterProxyModel界面似乎不太适合该任务,而是专注于静态角色和预编译规则。
我尝试QJSValue在 C++ 端使用属性,但似乎这是不可能的,C++ 代码只是不使用该属性类型进行编译。如果我将属性类型设置为,QVariant我会从 QML 收到错误消息,表明函数只能绑定到var属性。显然,var转换QVariant在这里并不像返回值那样起作用。
更新:
重新审视这个问题,我终于有了一个最终的解决方案,所以我决定添加一些更新。一、相关代码:
void set_filter(QJSValue f) {
if (f != m_filter) {
m_filter = f;
filterChanged();
invalidate();
}
}
void set_sorter(QJSValue f) {
if (f != m_sort) {
m_sort = f;
sorterChanged();
sort(0, Qt::DescendingOrder);
}
}
bool filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const {
if (!m_filter.isCallable()) return true;
QJSValueList l;
l.append(_engine->newQObject(sourceModel()->index(sourceRow, 0, sourceParent).data().value<QObject*>()));
return m_filter.call(l).toBool();
}
bool lessThan(const QModelIndex & left, const QModelIndex & right) const {
if (!m_sort.isCallable()) return false;
QJSValueList l;
l.append(_engine->newQObject(sourceModel()->data(left).value<QObject*>()));
l.append(_engine->newQObject(sourceModel()->data(right).value<QObject*>()));
return m_sort.call(l).toBool();
}
Run Code Online (Sandbox Code Playgroud)
我发现这个解决方案比 QQmlScriptString 和 QQmlExpression 二重奏更简单、更安全、性能更好,后者确实提供了通知自动更新,但正如 GrecKo 的答案下面的评论中已经详细阐述的那样,它有点不稳定,并不值得。
获取外部上下文属性更改自动更新的方法是在返回实际函子之前简单地引用它们:
filter: { expanded; SS.showHidden; o => expanded && (SS.showHidden ? true : !o.hidden) }
Run Code Online (Sandbox Code Playgroud)
这是一个使用新的简写函数语法的简单表达式,它引用expanded; SS.showHidden;以便在这些变化时触发重新计算,然后隐式返回函子
o => expanded && (SS.showHidden ? true : !o.hidden)
这类似于:
return function(o) { return expanded && (SS.showHidden ? true : !o.hidden) }
根据父节点是否展开、子节点是否隐藏以及隐藏对象是否仍然显示来过滤对象。
此解决方案无法自动响应 的更改o.hidden,因为o在求值时会插入函子中,并且无法在绑定表达式中引用,但这可以在需要动态响应此类更改的视图的委托中轻松实现:
Connections {
target: obj
onHiddenChanged: triggerExplicitEvaluation()
}
Run Code Online (Sandbox Code Playgroud)
请记住,用例涉及无模式/单一QObject*角色模型,该模型促进变形数据模型,其中模型项数据通过 QML 属性实现,因此任何角色或正则表达式库存过滤机制都不适用于此,但同时,这提供了使用单一机制基于任何标准和任意项目数据来实现排序和过滤的通用性,并且性能非常好,尽管我最初担心。它没有实现排序顺序,只需翻转比较表达式结果即可轻松实现排序顺序。
| 归档时间: |
|
| 查看次数: |
2070 次 |
| 最近记录: |