As you mentionned, you could use QJSValue. But that's pretty static. What if you want to use a filter like filter: function(o) { return o.size > slider.value; }
with a dynamic slider ? You'll have to manually call invalidateFilter()
.
As a more practical alternative, you could instead use QQmlScriptString
as a property & QQmlExpression
to execute it. Using QQmlExpression
allows you to be notified of context changes with setNotifyOnValueChanged
.
Your syntax would change to be like so : filter: o.size > slider.value
.
If you are looking for an out of the box solution, I've implemented this in a library of mine : SortFilterProxyModel on GitHub
You can take a look at ExpressionFilter
& ExpressionSorter
, those do the same as what you initially wanted. You can check the complete source code in the repo.
How to use it :
import SortFilterProxyModel 0.2
// ...
SortFilterProxyModel {
sourceModel: model
filters: ExpressionFilter { expression: model.size > 3 }
sorters: ExpressionSorter { expression: modelLeft.size < modelRight.size }
}
But as @dtech mentionned, the overhead of going back and forth between qml and c++ for each row of the model is quite noticeable. That's why I created more specific filters and sorters. In your case, we would use RangeFilter
and RoleSorter
:
import SortFilterProxyModel 0.2
// ...
SortFilterProxyModel {
sourceModel: model
filters: RangeFilter {
roleName: "size"
minimumValue > 3
minimumInclusive: true
}
sorters: RoleSorter { roleName: "size" }
}
Doing like this, we have a nice declarative API and the parameters are only passed once from qml to c++. All the filtering and sorting is then entirely done on the c++ side.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…