I have the following working code, which opens a QFileDialog with an extra column that shows the file name again (pointless, I know, but it’s a result of simplifying my issue):
from PySide2 import QtCore, QtWidgets
def __init__(self, parent=None):
super(MyProxyModel, self).__init__(parent)
self._parents = {}
def mapToSource(self, index):
if index.column() == 4:
return super(MyProxyModel, self).mapToSource(index)
def columnCount(self, index):
return 5
def data(self, index, role=QtCore.Qt.DisplayRole):
if role == QtCore.Qt.DisplayRole and index.column() == 4:
return self.index(index.row(), 0, self._parents[index]).data(role)
return super(MyProxyModel, self).data(index, role)
def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole):
if section == 4 and orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
return 'My Column'
return super(MyProxyModel, self).headerData(section, orientation, role)
def index
(self, row, column, parent
=QtCore.
QModelIndex()): if column == 4:
index = self.createIndex(row, column)
self._parents[index] = parent
return index
return super(MyProxyModel, self).index(row, column, parent)
def parent(self, index):
if index.column() == 4:
return super(MyProxyModel, self).parent(index)
dialog.setOption(dialog.DontUseNativeDialog, True)
dialog.setProxyModel(MyProxyModel(dialog))
dialog.exec_()
from PySide2 import QtCore, QtWidgets
class MyProxyModel(QtCore.QSortFilterProxyModel):
def __init__(self, parent=None):
super(MyProxyModel, self).__init__(parent)
self._parents = {}
def mapToSource(self, index):
if index.column() == 4:
return QtCore.QModelIndex()
return super(MyProxyModel, self).mapToSource(index)
def columnCount(self, index):
return 5
def data(self, index, role=QtCore.Qt.DisplayRole):
if role == QtCore.Qt.DisplayRole and index.column() == 4:
return self.index(index.row(), 0, self._parents[index]).data(role)
return super(MyProxyModel, self).data(index, role)
def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole):
if section == 4 and orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
return 'My Column'
return super(MyProxyModel, self).headerData(section, orientation, role)
def index(self, row, column, parent=QtCore.QModelIndex()):
if column == 4:
index = self.createIndex(row, column)
self._parents[index] = parent
return index
return super(MyProxyModel, self).index(row, column, parent)
def parent(self, index):
if index.column() == 4:
return QtCore.QModelIndex()
return super(MyProxyModel, self).parent(index)
QtWidgets.QApplication([])
dialog = QtWidgets.QFileDialog()
dialog.setOption(dialog.DontUseNativeDialog, True)
dialog.setProxyModel(MyProxyModel(dialog))
dialog.exec_()
To copy to clipboard, switch view to plain text mode
As you can see, parent() is returning an invalid index for items of column 4, and instead I’m retrieving the actual parent inside data(), which isn’t ideal. But if I try the following, it exits with an access violation:
(...)
def data(self, index, role=QtCore.Qt.DisplayRole):
if role == QtCore.Qt.DisplayRole and index.column() == 4:
# Either return causes access violation.
return self.index(index.row(), 0, self.parent(index)).data(role)
return self.index(index.row(), 0, index.parent()).data(role)
return index.sibling(index.row(), 0).data(role)
return super(MyProxyModel, self).data(index, role)
(...)
def parent(self, index):
if index.column() == 4:
return self._parents[index]
return super(MyProxyModel, self).parent(index)
(...)
(...)
def data(self, index, role=QtCore.Qt.DisplayRole):
if role == QtCore.Qt.DisplayRole and index.column() == 4:
# Either return causes access violation.
return self.index(index.row(), 0, self.parent(index)).data(role)
return self.index(index.row(), 0, index.parent()).data(role)
return index.sibling(index.row(), 0).data(role)
return super(MyProxyModel, self).data(index, role)
(...)
def parent(self, index):
if index.column() == 4:
return self._parents[index]
return super(MyProxyModel, self).parent(index)
(...)
To copy to clipboard, switch view to plain text mode
I also tried leveraging QModelIndex’s internal pointer, with the same result (access violation):
# No __init__() defined; data() exactly like above.
(...)
def index
(self, row, column, parent
=QtCore.
QModelIndex()): if column == 4:
return self.createIndex(row, column, parent)
return super(MyProxyModel, self).index(row, column, parent)
def parent(self, index):
if index.column() == 4:
return index.internalPointer()
return super(MyProxyModel, self).parent(index)
(...)
# No __init__() defined; data() exactly like above.
(...)
def index(self, row, column, parent=QtCore.QModelIndex()):
if column == 4:
return self.createIndex(row, column, parent)
return super(MyProxyModel, self).index(row, column, parent)
def parent(self, index):
if index.column() == 4:
return index.internalPointer()
return super(MyProxyModel, self).parent(index)
(...)
To copy to clipboard, switch view to plain text mode
Pretty sure I’m missing something, but I can’t figure out what it is…
Bookmarks