How to fix QSortFilterProxyModel() with QFileSystemModel() for sorting by size or date?
-
Here's the problem. I'm using
QFileSystemModel()
with the custom implementation ofQSortFilterProxyModel()
that does some sorting inside the folder (keeps..
at the top, etc.)
The problem is thatQSortFilterProxyModel()
doesn't correctly sort by file size or date - it uses the string representations instead of the actual size and date values.Here's the example:
from PySide6.QtCore import * from PySide6.QtGui import * from PySide6.QtWidgets import * if __name__ == '__main__': class Dialog(QDialog): def __init__(self, parent=None): super(Dialog, self).__init__(parent) self.initUI() self.model = QFileSystemModel() self.model.setRootPath(".") self.sorting_model = QSortFilterProxyModel() self.sorting_model.setSourceModel(self.model) # self.view.setModel(self.model) self.view.setModel(self.sorting_model) # self.view.setRootIndex(self.model.index(".")) self.view.setRootIndex(self.sorting_model.mapFromSource(self.model.index("."))) self.view.setSortingEnabled(True) self.view.setRootIsDecorated(False) def initUI(self): self.view = QTreeView(self) self.view.setWindowTitle('Simple Tree Model') self.view.setGeometry(10, 10, 600, 400) self.setGeometry(300, 300, 920, 620) import sys app = QApplication(sys.argv) dialog = Dialog() dialog.show() sys.exit(app.exec_())
In this example sorting won't work fine for date and size. If you switch to using
self.model
instead ofself.sorting model
(comment/uncomment in the section in the middle) you'll see that sorting by date and size works fine with plainQFileSystemModel()
.How to make it work the same way with
QSortFilterProxyModel()
? I tried implementingsort()
function and callingself.sourceModel().sort(column, order)
, but it didn't fully work.Thanks.
-
Hi,
I would go with reading the implementation of QFileSystemModel to see how it is done there.
By the way, do you have the same result with PySide2 ?
-
@SGaist It's the same in PySide2 and PySide6.
I know a possible workaround: I could slightly modify thedata()
function of my implementation ofQFileSystemModel()
so that it returns sizes asint
and dates in unified format then insidelessThan()
ofQSortFilterProxyModel()
I could convert date string to date usingQDateTime.fromString()
and sort by them, but that would be quite inelegant. -
I ended up with this solution (in
lessThan()
code of my proxy model):# size if source_left.column() == 1: return self.sourceModel().size(source_left) < self.sourceModel().size(source_right) # date if source_left.column() == 3: return self.sourceModel().lastModified(source_left).__le__(self.sourceModel().lastModified(source_right))
By the way, not sure if it's enough to check the column number of
source_left
only. Should I also check the column number ofsource_right
? -
@midnightdim
Yes, this is the correct way to compare sizes or dates.You may assume Qt infrastructure will only call
lessThan()
withsource_left.column() == source_right.column()
. You can put in anassert source_left.column() == source_right.column()
to verify.