【问题标题】:PyQt custom MongoDB modelPyQt 自定义 MongoDB 模型
【发布时间】:2018-04-10 18:45:41
【问题描述】:

我正在开发一个使用 PyQt 和 MongoDB 作为后端的应用程序。我的应用程序中有一个表 (QTableView) 应该填充来自 MongoDB 的数据,我想使用模型->视图架构。由于 Qt 没有 MongoDB 模型,我需要编写一个自定义模型。

这个数据目前(可以改变以适应这个问题)被组织成一个字典列表,像这样(实际数据更复杂):

[{"name":"some name","phone":"283891273218"}, {"name":"some other name","phone":"56958656556"}]

每个字典代表一行,字典的每个键是一列。经过几个小时的搜索,我几乎一无所获,代码是:

class CustomModel(QtCore.QAbstractTableModel):
    def __init__(self, parent=None, *args):
        super(CustomModel, self).__init__()
        self.datatable = None

    def update(self, dataIn):
        print 'Updating Model'
        self.datatable = dataIn
        #print 'Datatable : {0}'.format(self.datatable)

    def rowCount(self, parent=QtCore.QModelIndex()):
        return len(self.datatable)

    def columnCount(self, parent=QtCore.QModelIndex()):
        return len(self.datatable[0])

    def data(self, index, role=QtCore.Qt.DisplayRole):

        if role == QtCore.Qt.DisplayRole:
            i = index.row()
            j = index.column()
            #print self.datatable
        else:
            return QtCore.QVariant()

    def flags(self, index):
        return QtCore.Qt.ItemIsEnabled

如果我理解正确,方法data 应该用数据填充行和列,但我不知道该怎么做。此代码当前正在生成正确数量的行和列,但没有数据。

如果有任何帮助或建议,我将不胜感激。

【问题讨论】:

    标签: model-view-controller pyqt pymongo


    【解决方案1】:

    首先要确保从源中提取数据时的列顺序一致。由于在这种情况下数据源行是字典,因此无法保证迭代时的顺序一致(无论如何索引都不可用)。为确保顺序一致,请设置映射到数据源键的列索引的有序列表:

    class CustomModel(QtCore.QAbstractTableModel):
        columns = ['name', 'phone']
    

    如果您想重新使用此自定义模型来包装其他数据集,您可能不希望将列名与类如此紧密地耦合在一起。通过使用传递给初始化程序的必需实例变量,它可以很容易地变得更通用:

    class CustomModel(QtCore.QAbstractTableModel):
        def __init__(self, columns, parent=None):
            super(CustomModel, self).__init__(parent)
            self.columns = columns
            self.datatable = []
    ...
    model = CustomModel(['name', 'phone'])
    

    然后可以使用列名来确定更健壮的 columnCount,因为 len(self.datatable[0]) 会因空模型而失败:

    def columnCount(self, parent=QtCore.QModelIndex()):
        return len(self.columns)
    

    此外,您可以在 headerData() 的默认实现中使用有序列类变量:

    def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole):
        if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
            return self.columns[section].title()
    

    最后,使用列列表作为查找,将模型列索引转换为用于源数据的字典键,并从 data() 方法返回源数据值:

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if role == QtCore.Qt.DisplayRole:
            row = self.datatable[index.row()]
            column_key = self.columns[index.column()]
            return row[column_key]
        else:
            return None
    

    (注意PyQt4和PySide不需要使用QVariant AFAICT)

    【讨论】:

      猜你喜欢
      • 2012-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-08
      • 2012-07-06
      • 1970-01-01
      相关资源
      最近更新 更多