python - PyQt5 从模型中获取数据以在 QListView 中显示自定义小部件

标签 python user-interface model-view-controller pyqt5

我正在使用 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/

相关文章:

Android:在 fragment 交换方面如何保持 MVC 模式?

python - 使用类型在 python 中动态创建类 - 为什么创建的类对象不相同?

python - 使用Python SDK时如何防止GCS自动解压对象?

python - 尝试使用 Python 设置 GTK 窗口类型提示时出现 AttributeError

python - 与 Flask 应用程序同时运行 GUI

c# - 枚举双向搜索的用户界面设计

python - 如何在 Tkinter 中按下 Tab 键后捕获文本小部件的值?

python - 在Scrapy中,无法提取其中包含 "@"的链接文本

model-view-controller - 将 T4MVC 与构建脚本一起使用

java - JAX-RS 是否适合作为 MVC 框架?