我在 QML 中有一个 ListView,想要用我在 Python 中创建的 AbstractListModel 中的数据填充它。
AbtractListModel.py(我删除了像 rowCount() 这样的方法以保持示例清晰)
class StudentModel(QAbstractListModel):
def __init__(self)
super().__init()
self.studentList = []
self.studentList.append(Student("Peter", 22)
def data(self, index: QtCore.QModelIndex, role: int = ...) -> typing.Any:
if role == QtCore.Qt.DisplayRole:
return self.studentList[index]
return None
学生.py
class Student(object):
name = ""
age = 0
def __init__(self, name, age):
self.name = name
self.age = age
ListView.qml
ListView {
model: studentModel
delegate: Rectangle {
Text{ text: #name }
Text{ text: #age }
}
}
我如何访问代表中学生的姓名和年龄,以向他们展示我在哪里使用了“#name”和“#age”?
您至少必须实现 QAbstractListModel 的 rowCount、data 和 roleNames 方法:
from __future__ import annotations
import os
import sys
import typing
from dataclasses import dataclass, fields
from pathlib import Path
from PySide6.QtCore import (
QAbstractListModel,
QByteArray,
QCoreApplication,
QModelIndex,
QObject,
Qt,
QUrl,
)
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine
CURRENT_DIRECTORY = Path(__file__).resolve().parent
@dataclass
class Student:
name: str = ""
age: int = 0
class StudentModel(QAbstractListModel):
def __init__(self, parent: QObject | None) -> None:
super().__init__()
self._studend_list = []
self._studend_list.append(Student("Peter", 22))
def data(self, index: QModelIndex, role: int = Qt.DisplayRole) -> typing.Any:
if 0 <= index.row() < self.rowCount():
student = self._studend_list[index.row()]
name = self.roleNames().get(role)
if name:
return getattr(student, name.decode())
def roleNames(self) -> dict[int, QByteArray]:
d = {}
for i, field in enumerate(fields(Student)):
d[Qt.DisplayRole + i] = field.name.encode()
return d
def rowCount(self, index: QModelIndex = QModelIndex()) -> int:
return len(self._studend_list)
def add_student(self, student: Student) -> None:
self.beginInsertRows(QModelIndex(), self.rowCount(), self.rowCount())
self._studend_list.append(student)
self.endInsertRows()
def main() -> None:
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
student_model = StudentModel()
engine.rootContext().setContextProperty("studentModel", student_model)
filename = os.fspath(CURRENT_DIRECTORY / "main.qml")
url = QUrl.fromLocalFile(filename)
def handle_object_created(obj: QObject | None, obj_url: QUrl) -> None:
if obj is None and url == obj_url:
QCoreApplication.exit(-1)
engine.objectCreated.connect(handle_object_created, Qt.QueuedConnection)
engine.load(url)
student_model.add_student(Student("wileni", 23))
sys.exit(app.exec())
if __name__ == "__main__":
main()
import QtQuick
import QtQuick.Controls
ApplicationWindow {
id: root
width: 640
height: 480
visible: true
ListView {
model: studentModel
anchors.fill: parent
delegate: Row {
Text {
text: model.name
}
Text {
text: model.age
}
}
}
}