QDataWidgetMapper.addMapping(...)导致应用程序挂起

时间:2017-08-23 01:26:55

标签: python pyqt pyqt4

我很难在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()"非常困惑。映射,但我相信这是索引分配给数据成员的方式。无论如何,非常感谢任何帮助......我花了很多时间来学习这一点,到目前为止还没有任何真正的帮助。

1 个答案:

答案 0 :(得分:1)

我不确定您是否对Qt的模型 - 视图编程框架的类有很好的理解。我建议阅读its documentation(您可以跳过有关拖放和代理的部分)。如果有必要,请阅读几次,在我完全理解之前花了一段时间。

无论如何,重要的一点是,有一些场景,并且在这些场景中使用不同的类。从简单到复杂的顺序是:

  1. 使用便利类。您可以在拥有小型号时使用此功能,并且只有一个小部件可供您查看 该模型。在这种情况下,您使用convinience classes, 所有名称都以' Widget':QListWidgetQTableWidget结尾, 和QTreeWidget。它们没有链接到单独的模型类,您可以直接使用相应的项类填充它们:QListWidgetItem, 分别为QTableWidgetItemQTreeWidgetItem。所有这些类都不是要分类的!正如您现在所经历的那样,覆盖它们可能会导致未定义的行为。
  2. 使用标准模型类。当您拥有小型模型但希望在同一模型上拥有多个视图时,可以使用这些类。在这种情况下,您创建一个QStandardItemModel并用QStandardItem个对象填充它。然后,您可以创建一个或多个视图类(QListViewQTableViewQTreeView)并将它们连接到模型。
  3. 创建新模型。如果您拥有大型模型,这是最佳解决方案。您重写其中一个基类QAbstractListModel', 'QAbstactTableModel', or 'QAbstractItemModel(遗憾的是没有QAbstractTreeModel),并实现了各种方法。您应该覆盖哪些方法取决于您希望模型具有的功能(请参阅Model Subclassing Reference)。这种方法的好处是更高的性能和灵活性。您的模型实现可以使用常规Python数据结构,data方法将根据视图的请求仅返回可见单元格的数据。您可以使用常规的Python数据结构来存储数据,而无需事先将数据放入Qt项目对象中。
  4. 不要混淆上面的课程。也就是说,不要将小部件项目放在标准模型中,反之亦然。

    在不了解您的情况的情况下,我认为情景2最适合您。因此,我建议您制作QStandardModel并用QStandardItem个对象填充它。在第一次迭代中,我会使用QListViewQTableView来检查您的模型。只有当它正常工作时,我才能将其连接到DataWidgetMapper。从简单开始!

    最后,请在下次做出正确的MVCE。确保它完整!例如,不要使用像anInstanceOfMyCustomType这样的结构,但要向我们展示创建对象实例的实际代码。否则,您可能会遗漏重要信息。它还允许我们自己重现问题,如果需要调查并检查可能的答案。