具有QML和PyQt的项目列表

问题描述 投票:0回答:1

我想使用PyQt + QML方法创建一个以列表形式排列的GUI元素的简单列表。元素表示具有两个主要属性的项目:namestate。最初,列表中填充了一些编码对象,例如QT设置存储中的对象。问题是,我想将从存储中检索到的每个条目包装在我的类(专用模块)中。用伪代码:

from my_module import Project

initial_list = [{
    name: 'Spaceship',
    state: 'In progress'
}, {
    name: 'Aircraft',
    state: 'Done'
}, {
    name: 'Truck',
    state: 'Broken'
}]

projects = [Project(p) for p in initial_list]

用户可以单击该项目并执行一些任务(这就是为什么我希望该元素成为Project实例)。

我知道我应该有一个表示数据的模型,但是我为发现的分散示例而苦恼。我是否应该具有单个元素的模型以及整个列表模型?如何在Project子类中封装QObject实例?我最后的尝试是QAbstractListModel用作模型,ListView用作视觉表示。您能给我一个简单完整的例子吗?

python listview pyqt qml pyqt5
1个回答
0
投票

猜猜我已经自己弄清楚了。对于所有想以某种方式重复执行此任务的人:您确实需要继承QAbstractItemModelQAbstractListModel)来为您的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
        }
    }
}

所以您将得到类似这样的内容:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.