我很难在PyQt中学习模型/视图(请参阅此主题:Unable to inherit from QAbstractItemModel)。当我尝试添加映射分配时,我的应用程序挂起。这是我的自定义数据模型类:
class MyCustomDataModel(QAbstractItemModel):
def __init(self, parent = None):
super(MyCustomDataModel, self).__init__(parent)
self.parent = None
def rowCount(self, parent):
return 1
def data(self, index, role):
if not index.isValid():
return None
if role == Qt.DisplayRole or role == Qt.EditRole:
if index.column() == 0:
return self.parent.value0
elif index.column() == 1:
return self.parent.value1
elif index.column() == 1:
return self.parent.value2
def setData(self, index, value, role = Qt.EditRole):
if role == Qt.EditRole:
if index.column() == 0:
self.parent.value0 = value
elif index.column() == 1:
self.parent.value1 = value
elif index.column() == 2:
self.parent.value2 = value
self.dataChanged.emit(index, index)
这是尝试使用数据模型的类。它包含我想要映射到小部件的变量:
class MyCustomType(AnotherCustomTypeThatInheritsQListWidgetItem):
def __init__(self, parent = None):
super(MyCustomType, self).__init__(parent)
# Some member data:
self.value0 = 0
self.value1 = 1
self.value2 = 2
# Instantiate a model:
self.dataModel = MyCustomDataModel()
self.dataModel.parent = self
我有一个包含三个QLineEdit小部件的复合小部件:
class MyCompositeWidget(QWidget):
def __init__(self, parent = None):
super(MyCompositeWidget, self).__init__(parent)
self.dataMapper = QDataWidgetMapper()
# Instantiate three line edits:
self.lineEdit1 = QLineEdit()
self.lineEdit2 = QLineEdit()
self.lineEdit3 = QLineEdit()
# Add widgets to layout, set layout, etc. Not shown but widgets display properly.
def Activate(self, anInstanceofMyCustomType):
self.dataMapper.setModel(anInstanceOfMyCustomType.dataModel)
self.dataMapper.addMapping(self.lineEdit1, 0) # This line causes application to hang indefinately
self.dataMapper.addMapping(self.lineEdit2, 1)
self.dataMapper.addMapping(self.lineEdit3, 2)
在运行时,应用程序挂起指示的" addMapping"呼叫"激活(...)"功能。我发现在线教程非常不清楚,并且在这里遇到了障碍。我不得不承认我对" index.column()"非常困惑。映射,但我相信这是索引分配给数据成员的方式。无论如何,非常感谢任何帮助......我花了很多时间来学习这一点,到目前为止还没有任何真正的帮助。
答案 0 :(得分:1)
我不确定您是否对Qt的模型 - 视图编程框架的类有很好的理解。我建议阅读its documentation(您可以跳过有关拖放和代理的部分)。如果有必要,请阅读几次,在我完全理解之前花了一段时间。
无论如何,重要的一点是,有一些场景,并且在这些场景中使用不同的类。从简单到复杂的顺序是:
QListWidget
,QTableWidget
结尾,
和QTreeWidget
。它们没有链接到单独的模型类,您可以直接使用相应的项类填充它们:QListWidgetItem
,
分别为QTableWidgetItem
和QTreeWidgetItem
。所有这些类都不是要分类的!正如您现在所经历的那样,覆盖它们可能会导致未定义的行为。QStandardItemModel
并用QStandardItem
个对象填充它。然后,您可以创建一个或多个视图类(QListView
,QTableView
或QTreeView
)并将它们连接到模型。QAbstractListModel', 'QAbstactTableModel', or 'QAbstractItemModel
(遗憾的是没有QAbstractTreeModel
),并实现了各种方法。您应该覆盖哪些方法取决于您希望模型具有的功能(请参阅Model Subclassing Reference)。这种方法的好处是更高的性能和灵活性。您的模型实现可以使用常规Python数据结构,data
方法将根据视图的请求仅返回可见单元格的数据。您可以使用常规的Python数据结构来存储数据,而无需事先将数据放入Qt项目对象中。不要混淆上面的课程。也就是说,不要将小部件项目放在标准模型中,反之亦然。
在不了解您的情况的情况下,我认为情景2最适合您。因此,我建议您制作QStandardModel
并用QStandardItem
个对象填充它。在第一次迭代中,我会使用QListView
或QTableView
来检查您的模型。只有当它正常工作时,我才能将其连接到DataWidgetMapper
。从简单开始!
最后,请在下次做出正确的MVCE。确保它完整!例如,不要使用像anInstanceOfMyCustomType
这样的结构,但要向我们展示创建对象实例的实际代码。否则,您可能会遗漏重要信息。它还允许我们自己重现问题,如果需要调查并检查可能的答案。