Results 1 to 6 of 6

Thread: How can I properly implement QSortFilterProxyModel.parent to handle a virtual column?

  1. #1
    Join Date
    Sep 2021
    Location
    London, UK
    Posts
    4
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Question 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):

    Qt Code:
    1. from PySide2 import QtCore, QtWidgets
    2.  
    3.  
    4. class MyProxyModel(QtCore.QSortFilterProxyModel):
    5.  
    6. def __init__(self, parent=None):
    7. super(MyProxyModel, self).__init__(parent)
    8. self._parents = {}
    9.  
    10. def mapToSource(self, index):
    11. if index.column() == 4:
    12. return QtCore.QModelIndex()
    13. return super(MyProxyModel, self).mapToSource(index)
    14.  
    15. def columnCount(self, index):
    16. return 5
    17.  
    18. def data(self, index, role=QtCore.Qt.DisplayRole):
    19. if role == QtCore.Qt.DisplayRole and index.column() == 4:
    20. return self.index(index.row(), 0, self._parents[index]).data(role)
    21. return super(MyProxyModel, self).data(index, role)
    22.  
    23. def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole):
    24. if section == 4 and orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
    25. return 'My Column'
    26. return super(MyProxyModel, self).headerData(section, orientation, role)
    27.  
    28. def index(self, row, column, parent=QtCore.QModelIndex()):
    29. if column == 4:
    30. index = self.createIndex(row, column)
    31. self._parents[index] = parent
    32. return index
    33. return super(MyProxyModel, self).index(row, column, parent)
    34.  
    35. def parent(self, index):
    36. if index.column() == 4:
    37. return QtCore.QModelIndex()
    38. return super(MyProxyModel, self).parent(index)
    39.  
    40.  
    41. QtWidgets.QApplication([])
    42. dialog = QtWidgets.QFileDialog()
    43. dialog.setOption(dialog.DontUseNativeDialog, True)
    44. dialog.setProxyModel(MyProxyModel(dialog))
    45. 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:

    Qt Code:
    1. (...)
    2. def data(self, index, role=QtCore.Qt.DisplayRole):
    3. if role == QtCore.Qt.DisplayRole and index.column() == 4:
    4. # Either return causes access violation.
    5. return self.index(index.row(), 0, self.parent(index)).data(role)
    6. return self.index(index.row(), 0, index.parent()).data(role)
    7. return index.sibling(index.row(), 0).data(role)
    8. return super(MyProxyModel, self).data(index, role)
    9. (...)
    10. def parent(self, index):
    11. if index.column() == 4:
    12. return self._parents[index]
    13. return super(MyProxyModel, self).parent(index)
    14. (...)
    To copy to clipboard, switch view to plain text mode 

    I also tried leveraging QModelIndex’s internal pointer, with the same result (access violation):

    Qt Code:
    1. # No __init__() defined; data() exactly like above.
    2. (...)
    3. def index(self, row, column, parent=QtCore.QModelIndex()):
    4. if column == 4:
    5. return self.createIndex(row, column, parent)
    6. return super(MyProxyModel, self).index(row, column, parent)
    7.  
    8. def parent(self, index):
    9. if index.column() == 4:
    10. return index.internalPointer()
    11. return super(MyProxyModel, self).parent(index)
    12. (...)
    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…
    Last edited by Unai; 1st September 2021 at 17:11.

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,102
    Thanks
    289
    Thanked 844 Times in 831 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default 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.
    Last edited by d_stranz; 1st September 2021 at 16:42.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. #3
    Join Date
    Sep 2021
    Location
    London, UK
    Posts
    4
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default 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
    Last edited by Unai; 1st September 2021 at 17:03.

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,102
    Thanks
    289
    Thanked 844 Times in 831 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How can I properly implement QSortFilterProxyModel.parent to handle a virtual col

    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.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. #5
    Join Date
    Sep 2021
    Location
    London, UK
    Posts
    4
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default 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?

  6. #6
    Join Date
    Sep 2021
    Location
    London, UK
    Posts
    4
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Lightbulb Re: How can I properly implement QSortFilterProxyModel.parent to handle a virtual col


  7. The following user says thank you to Unai for this useful post:

    d_stranz (2nd September 2021)

Similar Threads

  1. Replies: 1
    Last Post: 14th June 2011, 15:50
  2. QSortFilterProxyModel not filtering properly
    By freemind in forum Qt Programming
    Replies: 9
    Last Post: 8th August 2010, 01:23
  3. Any way to properly handle Windows DPI setting?
    By vaddimka in forum Qt Programming
    Replies: 15
    Last Post: 16th May 2010, 10:03
  4. Unable to properly implement a QRubberBand
    By jamadagni in forum Qt Programming
    Replies: 1
    Last Post: 8th April 2009, 12:39

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.