pyqt链接列表视图和表视图与模型使用python字典

时间:2014-01-21 21:42:04

标签: python model-view-controller pyqt pyqt4

我正在学习PyQt4,我无法理解使用模型/视图设计的所有不同方法。

我有一个字典形式的数据,用于创建模型。

字典值是名为的元组,每个元组包含2个列表。

这些列表中的每一个都包含表的行数据。一个例子如下:

data = { key : ( [ [col1, col2, col3], row2 ], 
                 [ [col1, col2, col3], row2 ] 
       ) }

我的目标是要有一个列表视图,它是字典中所有键的列表。单击列表视图中的某个键将使用与该键关联的数据更新2个表视图。

我有工作代码,但我觉得这不是最好的做事方式。 仅举例来说,我使用了简化的数据结构,其中字典值是单个表。

我为列表视图创建了一个模型,并为表视图创建了一个使用相同数据的模型。我觉得可能有一种方法可以为两者使用一个模型,但我无法弄清楚如何链接它们并更改显示的值。

我的搜索让我读到了关于proxyModels,dataMappers,itemDelegates,QSortFilterProxyModel以及现在的TreeViews。但是当我的数据是字典时,我不知道使用哪个或如何实现它们。

实现上述目标的正确方法是什么?

我是否需要将字典中的数据更改为其他内容?

以下是我提出的示例代码:

from PyQt4 import QtCore, QtGui
import random
import sys

def build_mock_data(num_keys, num_rows=4, num_columns=3):
    result = {}
    key = "key"
    build_row = lambda: [random.randint(0,10) for _ in xrange(num_columns)]
    for i in xrange(num_keys):
        result[key+str(i)] = [build_row() for _ in xrange(num_rows)]
    return result

mock_data = build_mock_data(10)

class TableModel(QtCore.QAbstractTableModel):
    def __init__(self, data, parent=None):
        super(TableModel, self).__init__(parent)
        self._data = data
        # defualt key
        self.dict_key = 'key0'

    def set_key(self, key):
        self.beginResetModel()
        self.dict_key = key
        self.endResetModel()

    def rowCount(self, QModelIndex_parent=None, *args, **kwargs):
        return len(self._data[self.dict_key])

    def columnCount(self, QModelIndex_parent=None, *args, **kwargs):
        return len(self._data[self.dict_key][0])

    def data(self, QModelIndex, int_role=None):
        row = QModelIndex.row()
        column = QModelIndex.column()
        if int_role == QtCore.Qt.DisplayRole:
            return str(self._data[self.dict_key][row][column])

class ListModel(QtCore.QAbstractListModel):
    def __init__(self, data, parent=None):
        super(ListModel, self).__init__(parent)
        self._data = sorted(data.keys())

    def list_clicked(self, index):
        row = index.row()
        key = self._data[row]
        table_model.set_key(key)

    def rowCount(self, QModelIndex_parent=None, *args, **kwargs):
        return len(self._data)

    def data(self, QModelIndex, int_role=None):
        row = QModelIndex.row()
        if int_role == QtCore.Qt.DisplayRole:
            return str(self._data[row])

    def flags(self, QModelIndex):
        return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable


#########################################
# temporary just to get above code to run
app = QtGui.QApplication(sys.argv)

list_view = QtGui.QListView()
list_model = ListModel(mock_data)
list_view.setModel(list_model)
list_view.clicked.connect(list_model.list_clicked)
list_view.show()

table_view = QtGui.QTableView()
table_model = TableModel(mock_data)
table_view.setModel(table_model)
table_view.show()

sys.exit(app.exec_())

0 个答案:

没有答案