我正在使用 PyQt5 并尝试创建一个带有一些自定义数据结构(Recipe
)列表的 GUI,并且我将自定义小部件定义为 QWidget
的子类> 描述了它应该如何显示。
我正在尝试使用 MVC,所以我有一个 QListView
并且我对 QAbstractListModel
进行了子类化。
我希望列表包含我的自定义小部件而不仅仅是文本,因此我还为其定义了一个返回该小部件的项目委托(delegate)。也许我对这三个组件(模型、项目委托(delegate)、 View )如何协同工作的确切理解是有缺陷的,因为我不确定如何访问从模型的 data()
方法返回的任何内容并将其转换为我想在该列表单元格中显示的特定小部件。
示例代码:
class Recipe:
pass # custom data structure
class RecipeWidget(QWidget, RecipeWidgetUI):
def __init__(self, recipe, *args, **kwargs):
super(RecipeWidget, self).__init__(*args, **kwargs)
self.recipe = recipe
self.setupUi(self)
# some code here to populate the UI elements with data from self.recipe
class RecipeListModel(QAbstractListModel):
def __init__(self, recipes, *args, **kwargs):
super(RecipeListModel, self).__init__(*args, **kwargs)
self.recipes = recipes
def rowCount(self, index):
return len(self.recipes)
def data(self, index, role):
if role == Qt.DisplayRole:
return str(self.recipes[index.row()]) # this is the part I'm confused about
class RecipeItemDelegate(QItemDelegate):
def __init__(self, parent):
QItemDelegate.__init__(self, parent)
def createEditor(self, parent, option, index):
return RecipeWidget(recipe, parent=parent) # where do I get recipe from??
class MainWindow(...):
def __init__(self, ...):
...
self.model = RecipeListModel(recipes)
self.listView.setModel(self.model)
self.listView.setItemDelegate(RecipeItemDelegate(self.listView))
我知道模型中的 data(...)
函数应该返回一个字符串;我不明白的是:
- 如何返回我的
Recipe
数据结构?我是否必须以某种方式对其进行序列化,然后再反序列化? RecipeItemDelegate
在哪里查看data(...)
函数返回的内容以便正确构建食谱对象?
最佳答案
每个项目都可以根据角色保存多个数据属性。这些数据属性是 QVariants。您可以在 QVariant 中嵌入很多不同的东西,甚至是自定义对象。
我会说最好的做法是为显示角色使用字符串,并为其他事情使用 Qt.UserRole(或 Qt.UserRole + n)。您的委托(delegate)人仍然可以通过在查询项目数据时提供该角色来访问这些内容。
尽管我使用 C++ 进行开发,但我并不精通如何将 QVariant 的自定义类型与 PyQt5 一起使用。请注意,如果您要将 Qt 用于 Python 而不是 PyQt5,则无需使用 QVariant,只需设置和获取任何自定义 Python 变量即可。
关于python - PyQt5 从模型中获取数据以在 QListView 中显示自定义小部件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62314127/