[英]PyQt5 get data from model to show custom widget in QListView
我正在使用 PyQt5 並嘗試創建一個帶有一些自定義數據結構列表的 GUI ( Recipe
),並且我將自定義小部件定義為QWidget
的子類,描述了它應該如何顯示。 我正在嘗試使用 MVC,所以我有一個QListView
並且我對QAbstractListModel
進行了子類化。 我希望列表包含我的自定義小部件而不僅僅是文本,因此我還為其定義了一個返回該小部件的項目委托。 也許我對這三個組件(模型、項目委托、視圖)如何協同工作的確切理解是有缺陷的,因為我不確定如何訪問從 model 的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))
我知道 model 中的data(...)
function 應該返回一個字符串; 我不明白的是:
Recipe
數據結構? 我是否必須以某種方式序列化它然后再反序列化?RecipeItemDelegate
在哪里查看data(...)
function 返回的內容,以便正確構建配方 object?每個項目都可以根據角色保存多個數據屬性。 這些數據屬性是 QVariants。 您可以在 QVariant 中嵌入很多不同的東西,甚至是自定義對象。
我會說最好的做法是將字符串用於顯示角色,並將 Qt.UserRole(或 Qt.UserRole + n)用於其他用途。 您的委托人仍然可以通過在查詢項目數據時提供該角色來訪問這些內容。
盡管我使用 C++ 進行開發,但我並不精通如何將 QVariant 的自定義類型與 PyQt5 一起使用。請注意,如果您將 Qt 用於 Python 而不是 PyQt5,則無需使用 QVariant any,只需設置和獲取自定義 python 變量。
return self.recipes[index.row()]
。 但是如果要支持拖拽,QT需要能夠序列化數據。 現在讓我們在 self.recipes 中提供 python 索引,它可以被序列化。 return index.row() # which happens to be python index in the self.recipes
如果您希望代表支持編輯,則:
- createEditor() 應該創建用於更改 model 數據的小部件
- setEditorData() 應該用要操作的數據填充小部件。 像
editor.set_recipe(self.reference_to_recipes[index.data(Qt.DisplayRole)])
- updateEditorGeometry() 確保編輯器相對於項目視圖正確顯示。
- setModelData() 將更新后的數據返回到 model。例如
model.setData(index, editor.get_modified_recipe(), Qt.EditRole)
當然,model.setData() 需要能夠在 8488299540283838 上處理 Recipe 8828299540283838
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.