How can I properly implement QSortFilterProxyModel.parent to handle a virtual column?
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):
Code:
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_()
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:
Code:
(...)
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)
(...)
I also tried leveraging QModelIndex’s internal pointer, with the same result (access violation):
Code:
# 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)
(...)
Pretty sure I’m missing something, but I can’t figure out what it is…
Re: How can I properly implement QSortFilterProxyModel.parent to handle a virtual col
@Unai: For some reason, the forum put both of your posts into the "Moderation queue" for approval before they could become visible to the rest of the users. No idea why. I deleted the duplicate post and approved this one. Sorry about that.
I have created proxies with virtual columns, but in C++. I'll have to read through your code later and see if anything jumps out. There is a logical issue of what to do with "map to source" when the source index doesn't exist, and I think I have simply returned an invalid index. If you are relying on a pointer to something being stored in the QModelIndex, and that pointer is null, then that could certainly cause a segfault.
*Edit: You define (and access) a "self._parents" list (dictionary? I'm not a python expert), but I don't see anywhere that you are putting anything into this list. So calling self._parents[index] is probably the source of the crash.
Re: How can I properly implement QSortFilterProxyModel.parent to handle a virtual col
Thanks @d_stranz! Sorry for posting twice— I was a bit confused as I didn’t read the auto-closing pop-up the first time, which said a mod would need to approve it as I’m new here, so it’s all fine :)
Just realised that I’m constantly getting ‘Can't select indexes from different model or with different parents’ messages and it’s not letting me select any file, so I’m definitely doing something wrong :rolleyes:
Re: How can I properly implement QSortFilterProxyModel.parent to handle a virtual col
Quote:
Just realised that I’m constantly getting ‘Can't select indexes from different model or with different parents’ messages and it’s not letting me select any file, so I’m definitely doing something wrong
Yes. Your view's selection model operates on the proxy, not the source model. Any QModelIndex instances retrieved from the selection model have to be mapped back to the source via the proxy's mapToSource() call.
Re: How can I properly implement QSortFilterProxyModel.parent to handle a virtual col
That makes sense, but shouldn’t it get automatically accounted for by QFileDialog’s selection model already?
Re: How can I properly implement QSortFilterProxyModel.parent to handle a virtual col