Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
pyqt链接列表视图和表视图,带有使用python字典的模型_Python_Model View Controller_Pyqt_Pyqt4 - Fatal编程技术网

pyqt链接列表视图和表视图,带有使用python字典的模型

pyqt链接列表视图和表视图,带有使用python字典的模型,python,model-view-controller,pyqt,pyqt4,Python,Model View Controller,Pyqt,Pyqt4,我正在学习PyQt4,我很难理解使用模型/视图设计的所有不同方式 我有字典形式的数据,用于创建模型 字典值是namedtuples,每个值包含2个列表 这些列表中的每一个都包含一个表的行数据。示例如下所示: data = { key : ( [ [col1, col2, col3], row2 ], [ [col1, col2, col3], row2 ] ) } 我的目标是拥有一个列表视图,它是字典中所有键的列表。单击列表视图中的键将使用与

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

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

字典值是namedtuples,每个值包含2个列表

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

data = { key : ( [ [col1, col2, col3], row2 ], 
                 [ [col1, col2, col3], row2 ] 
       ) }
我的目标是拥有一个列表视图,它是字典中所有键的列表。单击列表视图中的键将使用与该键关联的数据更新2个表视图

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

我为列表视图和表视图创建了一个模型,它们都使用相同的数据。我觉得可能有一种方法可以同时使用一个模型,但我不知道如何链接它们并更改显示的值

我的搜索让我阅读了有关proxyModels、DataMapper、itemDelegates、QSortFilterProxyModel以及现在的TreeView的内容。但当我的数据是字典时,我不知道该使用哪一个或如何实现它们

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

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

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

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_())

这种方法没有任何问题。在Python2.7中,您可能希望使用一个有序的dict,因此在维护项目顺序方面,键的行为更像一个真实的列表。从概念上讲,键只是碰巧与另一个项目列表(字典值)有关系的项目的“列表”。使用dict只是对“键列表”应用一些约束,以确保它们是唯一的、无序的(使用有序dict?),等等。这很像一个具有一列和唯一约束的关系表,其中的行映射到第二个表中的行。你的解决方案一点问题也没有。很好。让多个模型以不同的方式呈现相同的底层数据,或者在彼此之上分层,也没有什么错。