Model view controller PyQt自定义MongoDB模型

Model view controller PyQt自定义MongoDB模型,model-view-controller,pyqt,pymongo,Model View Controller,Pyqt,Pymongo,我正在开发一个应用程序,使用PyQt和MongoDB作为后端。在我的应用程序中有一个表(QTableView),应该用来自MongoDB的数据填充该表,我希望使用模型->视图体系结构。因为Qt没有MongoDB的模型,所以我需要编写一个自定义模型 此数据当前(可以更改以适应此问题)组织为字典列表,如下所示(实际数据更复杂): 每个字典代表一行,字典的每个键代表一列。经过几个小时的搜索,我几乎一无所获,代码是: class CustomModel(QtCore.QAbstractTableMode

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

此数据当前(可以更改以适应此问题)组织为字典列表,如下所示(实际数据更复杂):

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

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
应该用数据填充行和列,但我不知道怎么做。此代码当前正在生成没有数据的正确行数和列数


如果您能提供任何帮助或建议,我将不胜感激。

一个好的开始就是确保从源代码中提取数据时列顺序一致。因为在这种情况下,数据源行是字典,所以在迭代时不能保证顺序一致(索引无论如何都不可用)。为确保顺序一致,请设置映射到数据源键的列索引的有序列表:

类CustomModel(QtCore.QAbstractTableModel):
列=['name','phone']
如果希望重用此自定义模型包装其他数据集,可能不希望列名与类紧密耦合。通过使用传递给初始值设定项的必需实例变量,可以很容易地使其更通用:

类CustomModel(QtCore.QAbstractTableModel):
def uuu init uuu(self,columns,parent=None):
超级(自定义模型,自).\u初始化\u(父级)
self.columns=列
self.datatable=[]
...
model=CustomModel(['name','phone']))
然后可以使用列名来确定columnCount,因为len(self.datatable[0])将在模型为空时失败,因此columnCount也更可靠:

def columnCount(self,parent=QtCore.QModelIndex()):
返回长度(自列)
此外,您还可以在headerData()的默认实现中使用ordered columns类变量:

def headerData(self、section、orientation、role=QtCore.Qt.DisplayRole):
如果方向==QtCore.Qt.Horizontal且角色==QtCore.Qt.DisplayRole:
返回self.columns[section].title()
最后,使用列列表作为查找,将模型列索引转换为字典键,以便在源数据中使用,并从data()方法返回源数据值:

def数据(self,index,role=QtCore.Qt.DisplayRole):
如果角色==QtCore.Qt.DisplayRole:
row=self.datatable[index.row()]
column\u key=self.columns[index.column()]
返回行[列\u键]
其他:
一无所获

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

一个好的开始是确保从源中提取数据时列顺序一致。因为在这种情况下,数据源行是字典,所以在迭代时不能保证顺序一致(索引无论如何都不可用)。为确保顺序一致,请设置映射到数据源键的列索引的有序列表:

类CustomModel(QtCore.QAbstractTableModel):
列=['name','phone']
如果希望重用此自定义模型包装其他数据集,可能不希望列名与类紧密耦合。通过使用传递给初始值设定项的必需实例变量,可以很容易地使其更通用:

类CustomModel(QtCore.QAbstractTableModel):
def uuu init uuu(self,columns,parent=None):
超级(自定义模型,自).\u初始化\u(父级)
self.columns=列
self.datatable=[]
...
model=CustomModel(['name','phone']))
然后可以使用列名来确定columnCount,因为len(self.datatable[0])将在模型为空时失败,因此columnCount也更可靠:

def columnCount(self,parent=QtCore.QModelIndex()):
返回长度(自列)
此外,您还可以在headerData()的默认实现中使用ordered columns类变量:

def headerData(self、section、orientation、role=QtCore.Qt.DisplayRole):
如果方向==QtCore.Qt.Horizontal且角色==QtCore.Qt.DisplayRole:
返回self.columns[section].title()
最后,使用列列表作为查找,将模型列索引转换为字典键,以便在源数据中使用,并从data()方法返回源数据值:

def数据(self,index,role=QtCore.Qt.DisplayRole):
如果角色==QtCore.Qt.DisplayRole:
row=self.datatable[index.row()]
column\u key=self.columns[index.column()]
返回行[列\u键]
其他:
一无所获
(注意PyQt4和PySide不需要使用QVariant AFAICT)

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