This example illustrates how QSortFilterProxyModel and QAbstractListModel can be used to display a list of filterable items in QML and Python.
Run filtering.py; it will load filtering.qml which will need to be located in the same directory.
This example illustrates how QSortFilterProxyModel and QAbstractListModel can be used to display a list of filterable items in QML and Python.
Run filtering.py; it will load filtering.qml which will need to be located in the same directory.
| import sys | |
| from PyQt5 import QtCore, QtGui, QtQuick | |
| class Model(QtCore.QAbstractListModel): | |
| def __init__(self, parent=None): | |
| super(Model, self).__init__(parent) | |
| self.items = [ | |
| {"name": "Item1"}, | |
| {"name": "Item2"}, | |
| {"name": "Item3"}, | |
| {"name": "Item4"}, | |
| {"name": "Item5"}, | |
| {"name": "Item6"}, | |
| {"name": "Item12"}, | |
| {"name": "Item13"}, | |
| {"name": "Item14"}, | |
| ] | |
| self.roles = { | |
| QtCore.Qt.UserRole + 1: "name" | |
| } | |
| def rowCount(self, parent=QtCore.QModelIndex()): | |
| return len(self.items) | |
| def data(self, index, role=QtCore.Qt.DisplayRole): | |
| try: | |
| item = self.items[index.row()] | |
| except IndexError: | |
| return QtCore.QVariant() | |
| if role in self.roles: | |
| return item.get(self.roles[role], QtCore.QVariant()) | |
| return QtCore.QVariant() | |
| def roleNames(self): | |
| return self.roles | |
| app = QtGui.QGuiApplication(sys.argv) | |
| view = QtQuick.QQuickView() | |
| model = Model() | |
| proxy = QtCore.QSortFilterProxyModel() | |
| proxy.setSourceModel(model) | |
| proxy.setFilterRole(model.roles.keys()[0]) | |
| proxy.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive) | |
| engine = view.engine() | |
| context = engine.rootContext() | |
| context.setContextProperty("qmodel", proxy) | |
| view.setSource(QtCore.QUrl("filtering.qml")) | |
| view.setResizeMode(view.SizeRootObjectToView) | |
| view.show() | |
| app.exec_() |
| import QtQuick 2.3 | |
| import QtQuick.Controls 1.3 | |
| Rectangle { | |
| width: 400 | |
| height: 500 | |
| color: "brown" | |
| TextField { | |
| id: edit | |
| placeholderText: "Filter.." | |
| anchors.top: parent.top | |
| anchors.left: parent.left | |
| anchors.right: parent.right | |
| anchors.margins: 10 | |
| onTextChanged: qmodel.setFilterFixedString(text) | |
| } | |
| Rectangle { | |
| color: "white" | |
| radius: 2 | |
| anchors.top: edit.bottom | |
| anchors.left: parent.left | |
| anchors.right: parent.right | |
| anchors.bottom: parent.bottom | |
| anchors.margins: 10 | |
| ListView { | |
| id: listView | |
| clip: true | |
| model: qmodel | |
| spacing: 10 | |
| anchors.fill: parent | |
| anchors.margins: 5 | |
| delegate: Text { | |
| text: name | |
| } | |
| } | |
| } | |
| } |
Very nice example. Thank you!
One small update: I had to set the object ownership for the proxy, or I would get a segfault: