View a list of pyqt links and present a table using a model using a python dictionary

I am learning PyQt4 and I am having trouble understanding all the ways to use the Model / View design.

I have data in the form of a dictionary, which I use to create a model.

The dictionary values ​​are namedtuples, which contain 2 lists.

Each of these lists contains row data for the table. An example would look like this:

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

My goal is to have a list view, which is a list of all the keys from a dictionary. Clicking on a key in the list view will update 2 table views with the data associated with this key.

I have working code , but I feel that this is not the best way to do something. For example, I used a simplified data structure , where dictionary values ​​are single tables.

I created a model for presenting a list and a model for presenting tables that use the same data. I feel that it is possible to use one model for both, but I could not understand how to relate them and change the displayed values.

My search made me read about proxyModels, dataMappers, itemDelegates, QSortFilterProxyModel and now TreeViews. But I do not know what to use or how to implement them when my data is a dictionary.

What is the correct way to achieve the above?

Do I need to change the data from the dictionary to something else?

Here is an example of the code I came up with:

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

:

1798
1782
?
1687
?
1170
1056

All Articles