I've been working with Qt for a few months now and am still having some trouble with understanding the model view architecture. I have some data structure of the following form (I use PyQt5):

Qt Code:
  1. class MyData:
  2. def __init__(self):
  3. self.name = "Item 1"
  4. self.value = "Value 1"
  5.  
  6. # List of lists
  7. self.attributes = [
  8. ["Attr 1", "100", "560", "300", "1200"]
  9. ,["Attr 2", "50", "40", "470", "20"]
  10. ,["Attr 3", "75", "30", "30", "100"]
  11. ,["Attr 4", "300", "300", "280", "400"]
  12. ]
To copy to clipboard, switch view to plain text mode 

I want to display this data in two different views. (read only) The 'name' and 'value' attributes in one view ( 2 columns ). And the list of attributes in another view ( 5 Columns ) when whichever item in the first view is selected. I threw together a quick representation of what I want in Qt Designer:

form.png

Ideally I would like to use a single model (QAbstractItemModel, or maybe even just QAbstractTableModel?) I believe a main model and two Proxy models are probably the way to do this? With the proxy models having their own reimplementation of headerData(). But how does that work then with columnCount()? Do I have to reimplement that as well in each proxy? Here is somewhat pseudocode of what my current main model looks like:

Qt Code:
  1. class MyModel(QAbstractItemModel):
  2. def __init__(self, parent=None)
  3. super(MyModel, self).__init__(parent)
  4. self.myData = [] # List of MyData() instances
  5.  
  6. def columnCount(self, parent):
  7. # Do I have to check which view is requesting the column count?
  8.  
  9. if firstView:
  10. return 2
  11. else:
  12. return 5
  13.  
  14. def rowCount(self, parent):
  15. if firstView:
  16. return len(self.myData)
  17. else:
  18. return len(self.myData[parent.row()].attributes) # ??
  19.  
  20. def flags(self, index):
  21. return Qt.ItemIsEnabled | Qt.ItemIsSelectable
  22.  
  23. def headerData(self, section, orientation, role):
  24. pass # Reimplemented in each proxy model?
  25.  
  26. def parent(index):
  27. # I have no idea how this needs to be implemented since the data in each view is essentially a table, but I still probably need some sort of parent index
  28. return QModelIndex()
  29.  
  30. def index(row, column, parent):
  31. return createIndex(row, column, self.myData[row]) # Probably just use internalPointer() in data()?
  32.  
  33. def data(self, index, role):
  34. # Again, I'm not sure if I implement this in the main model or each of the proxy models?
  35.  
  36. if not index.isValid():
  37. return None
  38.  
  39. data = index.internalPointer()
  40. if role == Qt.DisplayRole:
  41. if index.column() == 0:
  42. return ...
To copy to clipboard, switch view to plain text mode 

def insertRow(MyData)
# I would implement some insert method to insert into self.myData

I would then connect the selectionChanged signal for the first view to a slot that would reset the proxy model for the second view? And probably have to do setRootIndex()? Again I'm a bit lost on how to go about doing this and would love to see a working example with the above idea. The actual modeling of the structure when there is a list that needs to be displayed in a different view is what's really confusing me.

Feel free to respond in C++ or PyQt. I can understand both. Any advice would be appreciated. Thanks.