我猜是我自己想出来的。对于所有想要以某种方式重复该任务的人:您确实需要继承 QAbstractItemModel (QAbstractListModel) 以为您的 QML 提供模型(您不需要子类化单个项目,尽管我找到了方法一个有效的案例)。
Python:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
from PyQt5.QtCore import QCoreApplication, QUrl, QAbstractItemModel, pyqtProperty, QAbstractListModel, QModelIndex, \
QObject, QVariant, Qt
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQuick import QQuickView
import mylib
class ProjectListItem(QObject):
def __init__(self, project: mylib.Project, parent=None):
super().__init__(parent)
self.project = project
@pyqtProperty('QString')
def name(self):
return self.project.path.name
@pyqtProperty('QString')
def state(self):
return str(self.project.state)
class ProjectsList(QAbstractListModel):
def __init__(self, projects: list, parent=None):
super().__init__(parent)
self.projects = projects
def rowCount(self, parent=None, *args, **kwargs):
return len(self.projects)
def data(self, index: QModelIndex, role=None):
# print(index, role)
if role == Qt.DisplayRole:
return self.projects[index.row()]
def addProject(self, project):
self.beginInsertRows(QModelIndex(), self.rowCount(), self.rowCount())
self.projects.append(project)
self.endInsertRows()
if __name__ == '__main__':
app = QGuiApplication(sys.argv)
projects = ProjectsList([])
projects.addProject(ProjectListItem(mylib.Project('Abc')))
projects.addProject(ProjectListItem(mylib.Project('Def')))
projects.addProject(ProjectListItem(mylib.Project('Ghi')))
view = QQuickView()
view.setResizeMode(QQuickView.SizeRootObjectToView)
view.rootContext().setContextProperty('projectsModel', projects)
view.setSource(QUrl('main.qml'))
sys.exit(app.exec_())
QML:
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("PyQt5 love QML")
color: "whitesmoke"
GridLayout {
columns: 2
rows: 1
ListView {
width: 200; height: 250
model: projectsModel
delegate: Item {
id: projectListItem
width: ListView.view.width
height: 40
Column {
Text { text: '<b>Name:</b> ' + display.name }
Text { text: '<b>State:</b> ' + display.state }
}
MouseArea {
anchors.fill: parent
onClicked: { projectListItem.ListView.view.currentIndex = index; }
}
}
highlight: Rectangle { color: "lightsteelblue"; radius: 5 }
focus: true
}
}
}
那么你会得到这样的东西: