我正在学习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_())