将 QAbstractListModel 与 QML 同步
Sync QAbstractListModel with QML
我有一个实现 QAbstractListModel 的简单 StudentListModel class。
class StudentListModel(QAbstractListModel):
NAME = Qt.UserRole + 1
AGE = Qt.UserRole + 2
def __init__(self, students):
super().__init__()
self.students = students
def roleNames(self):
return {
StudentListModel.NAME: b'name',
StudentListModel.AGE: b'age',
}
def rowCount(self, parent=None, *args, **kwargs):
return len(self.students)
def data(self, QModelIndex, role=None):
row = self.students[QModelIndex.row()]
if role == StudentListModel.NAME:
return row["name"]
elif role == StudentListModel.AGE:
return row["age"]
return None
def remove(self, index):
self.students.pop(index)
StudentListModel 被传递到 QML 文件。 QML 将显示模型条目。
import QtQuick 2.15
import QtQuick.Controls 2.15
Rectangle {
id: container
signal remove(int index)
Column {
spacing: 15
Repeater {
model: studentListModel
Row {
spacing: 10
Text {
text: model.name
}
Button {
text: "Remove"
onClicked: container.remove(index)
}
}
}
}
}
此处表示连接 QML 和 StudentListModel 的代码:
def main():
students = [
{"name": "Vitaliy ", "age": "21"},
{"name": "Eugene", "age": "26"},
{"name": "Tommy", "age": "26"}
]
model = StudentListModel(students)
app = QApplication(sys.argv)
widget = QQuickWidget()
widget.setSource(QUrl('stack.qml'))
widget.rootContext().setContextProperty('studentListModel', model)
widget.rootObject().remove.connect(lambda index: model.remove(index))
widget.setGeometry(0, 0, 320, 800)
widget.show()
return app.exec_()
if __name__ == '__main__':
sys.exit(main())
下面是应用程序的屏幕截图:
在 QML 中显示模型条目没有问题。问题是当我想删除一个条目时。当我点击删除时,QML 获取点击条目的索引并发送信号。 main() 块将通过 lambda 函数处理信号发射。 Lambda 函数将接收索引,并通过传递接收到的索引从模型中调用 remove 方法。在此之后,模型将删除该条目,但 QML 不会显示更新后的模型。有没有办法将模型与 QML 同步,以便在删除条目时,它也会在 QML 中删除?
您必须分别在删除前后调用 beginRemoveRows 和 endRemoveRows 方法:
class StudentListModel(QAbstractListModel):
NAME = Qt.UserRole + 1
AGE = Qt.UserRole + 2
def __init__(self, students):
super().__init__()
self.students = students
def roleNames(self):
return {
StudentListModel.NAME: b"name",
StudentListModel.AGE: b"age",
}
def rowCount(self, parent=QModelIndex()):
return len(self.students)
def data(self, index, role=Qt.DisplayRole):
row = self.students[index.row()]
if role == StudentListModel.NAME:
return row["name"]
elif role == StudentListModel.AGE:
return row["age"]
def remove(self, index):
self.beginRemoveRows(QModelIndex(), index, index)
self.students.pop(index)
self.endRemoveRows()
我有一个实现 QAbstractListModel 的简单 StudentListModel class。
class StudentListModel(QAbstractListModel):
NAME = Qt.UserRole + 1
AGE = Qt.UserRole + 2
def __init__(self, students):
super().__init__()
self.students = students
def roleNames(self):
return {
StudentListModel.NAME: b'name',
StudentListModel.AGE: b'age',
}
def rowCount(self, parent=None, *args, **kwargs):
return len(self.students)
def data(self, QModelIndex, role=None):
row = self.students[QModelIndex.row()]
if role == StudentListModel.NAME:
return row["name"]
elif role == StudentListModel.AGE:
return row["age"]
return None
def remove(self, index):
self.students.pop(index)
StudentListModel 被传递到 QML 文件。 QML 将显示模型条目。
import QtQuick 2.15
import QtQuick.Controls 2.15
Rectangle {
id: container
signal remove(int index)
Column {
spacing: 15
Repeater {
model: studentListModel
Row {
spacing: 10
Text {
text: model.name
}
Button {
text: "Remove"
onClicked: container.remove(index)
}
}
}
}
}
此处表示连接 QML 和 StudentListModel 的代码:
def main():
students = [
{"name": "Vitaliy ", "age": "21"},
{"name": "Eugene", "age": "26"},
{"name": "Tommy", "age": "26"}
]
model = StudentListModel(students)
app = QApplication(sys.argv)
widget = QQuickWidget()
widget.setSource(QUrl('stack.qml'))
widget.rootContext().setContextProperty('studentListModel', model)
widget.rootObject().remove.connect(lambda index: model.remove(index))
widget.setGeometry(0, 0, 320, 800)
widget.show()
return app.exec_()
if __name__ == '__main__':
sys.exit(main())
下面是应用程序的屏幕截图:
在 QML 中显示模型条目没有问题。问题是当我想删除一个条目时。当我点击删除时,QML 获取点击条目的索引并发送信号。 main() 块将通过 lambda 函数处理信号发射。 Lambda 函数将接收索引,并通过传递接收到的索引从模型中调用 remove 方法。在此之后,模型将删除该条目,但 QML 不会显示更新后的模型。有没有办法将模型与 QML 同步,以便在删除条目时,它也会在 QML 中删除?
您必须分别在删除前后调用 beginRemoveRows 和 endRemoveRows 方法:
class StudentListModel(QAbstractListModel):
NAME = Qt.UserRole + 1
AGE = Qt.UserRole + 2
def __init__(self, students):
super().__init__()
self.students = students
def roleNames(self):
return {
StudentListModel.NAME: b"name",
StudentListModel.AGE: b"age",
}
def rowCount(self, parent=QModelIndex()):
return len(self.students)
def data(self, index, role=Qt.DisplayRole):
row = self.students[index.row()]
if role == StudentListModel.NAME:
return row["name"]
elif role == StudentListModel.AGE:
return row["age"]
def remove(self, index):
self.beginRemoveRows(QModelIndex(), index, index)
self.students.pop(index)
self.endRemoveRows()