gpt4 book ai didi

python - 带有 QML 和 PyQt 的项目列表

转载 作者:行者123 更新时间:2023-12-01 06:40:44 24 4
gpt4 key购买 nike

我想使用 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 作为视觉表示。您能给我提供一个最小的完整示例吗?

最佳答案

我想我已经自己弄清楚了。对于所有以某种方式想要重复该任务的人:您确实需要子类化 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
}
}
}

那么你会得到这样的结果:

enter image description here

关于python - 带有 QML 和 PyQt 的项目列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59469563/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com