簡體   English   中英

在 QML 中使用 ListModel (Python/Pyside6)

[英]Using ListModel (Python/Pyside6) in QML

我在 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

列表視圖.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
            }

        }

    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM