Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. How can I properly implement QSortFilterProxyModel.parent() to handle a virtual column?
QtWS25 Last Chance

How can I properly implement QSortFilterProxyModel.parent() to handle a virtual column?

Scheduled Pinned Locked Moved Solved Qt for Python
pyside2qt for pythonpython
4 Posts 2 Posters 484 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • U Offline
    U Offline
    Unai
    wrote on last edited by
    #1

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

    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)
    (...)
    

    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)
    (...)
    

    Pretty sure I’m missing something, but I can’t figure out what it is…

    1 Reply Last reply
    0
    • SGaistS SGaist

      Hi and welcome to devnet,

      You can take some inspiration from KDE's KExtraColumnsProxyModel.

      U Offline
      U Offline
      Unai
      wrote on last edited by
      #4

      Thanks @SGaist! I just got a solution on StackOverflow, so I’m marking this as solved, but it’s always great to see how the pros do it, so I’m definitely reading about KExtraColumnsProxyModel too 😊

      1 Reply Last reply
      2
      • U Offline
        U Offline
        Unai
        wrote on last edited by
        #2

        Huh, 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 😅

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #3

          Hi and welcome to devnet,

          You can take some inspiration from KDE's KExtraColumnsProxyModel.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          U 1 Reply Last reply
          1
          • SGaistS SGaist

            Hi and welcome to devnet,

            You can take some inspiration from KDE's KExtraColumnsProxyModel.

            U Offline
            U Offline
            Unai
            wrote on last edited by
            #4

            Thanks @SGaist! I just got a solution on StackOverflow, so I’m marking this as solved, but it’s always great to see how the pros do it, so I’m definitely reading about KExtraColumnsProxyModel too 😊

            1 Reply Last reply
            2

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved