I've come up with a solution using a QIdentityProxyModel for the bottom view and just using the main model for the top view. I connect the currentRowChanged() signal from the top views selection model to a slot that simply does the following:
def updateProxyModel(current, previous)
ProxyModel.beginResetModel()
ProxyModel.selectedRow = current.row()
ProxyModel.endResetModel()
def updateProxyModel(current, previous)
ProxyModel.beginResetModel()
ProxyModel.selectedRow = current.row()
ProxyModel.endResetModel()
To copy to clipboard, switch view to plain text mode
I did have to reimplement index() as the base implementation of QAbstractTableModel calls hasIndex() which checks the rowCount() and columnCount() of only the main model, and would never generate indexes above 2 columns for the proxy model. But this was ok, because I like to use internalPointer() anyway to save on a little bit of typing in the data() methods
Main model:
def __init__(self, data, parent=None):
super(MainModel, self).__init__(parent)
self.headers = ('Name', 'Value')
self.data = data
return len(self.headers)
return len(self.data)
def index(self, row, col, parent=None):
return self.createIndex(row, col, self.data[row])
def flags(self, index):
return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemNeverHasChildren
def headerData(self, column, orientation, role):
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
return self.headers[column]
def data(self, index, role=Qt.DisplayRole):
if not index.isValid():
return None
rowData = index.internalPointer()
col = index.column()
if role == Qt.DisplayRole:
if col == 0:
return rowData.name
if col == 1:
return rowData.value
return None
class MainModel(QAbstractTableModel):
def __init__(self, data, parent=None):
super(MainModel, self).__init__(parent)
self.headers = ('Name', 'Value')
self.data = data
def columnCount(self, parent=QModelIndex()):
return len(self.headers)
def rowCount(self, parent=QModelIndex()):
return len(self.data)
def index(self, row, col, parent=None):
return self.createIndex(row, col, self.data[row])
def flags(self, index):
return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemNeverHasChildren
def headerData(self, column, orientation, role):
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
return self.headers[column]
def data(self, index, role=Qt.DisplayRole):
if not index.isValid():
return None
rowData = index.internalPointer()
col = index.column()
if role == Qt.DisplayRole:
if col == 0:
return rowData.name
if col == 1:
return rowData.value
return None
To copy to clipboard, switch view to plain text mode
Proxy Model:
class ProxyModel(QIdentityProxyModel):
def __init__(self, data, parent=None):
super(ProxyModel, self).__init__(parent)
self.data = data
self.headers = ('Attribute', 'Width', 'Height', 'Pos X', 'Pos Y')
self.selectedRow = None
def headerData(self, column, orientation, role=None):
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
return self.headers[column]
if parent.isValid():
return 0
return len(self.headers)
if parent.isValid() or not self.selectedRow:
return 0
return len(self.data[self.selectedRow].attributes)
def data(self, index, role=Qt.DisplayRole):
if not index.isValid() or not self.selectedRow:
return None
col = index.column()
row = index.row()
if role == Qt.DisplayRole:
return self.data[self.selectedRow].attributes[row][col]
return None
class ProxyModel(QIdentityProxyModel):
def __init__(self, data, parent=None):
super(ProxyModel, self).__init__(parent)
self.data = data
self.headers = ('Attribute', 'Width', 'Height', 'Pos X', 'Pos Y')
self.selectedRow = None
def headerData(self, column, orientation, role=None):
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
return self.headers[column]
def columnCount(self, parent=QModelIndex()):
if parent.isValid():
return 0
return len(self.headers)
def rowCount(self, parent=QModelIndex()):
if parent.isValid() or not self.selectedRow:
return 0
return len(self.data[self.selectedRow].attributes)
def data(self, index, role=Qt.DisplayRole):
if not index.isValid() or not self.selectedRow:
return None
col = index.column()
row = index.row()
if role == Qt.DisplayRole:
return self.data[self.selectedRow].attributes[row][col]
return None
To copy to clipboard, switch view to plain text mode
Decent solution? What could be done better or differently?
Bookmarks