I would like to implement the file browser on PySide6, and my goals are:
..
always at the top (regardless of the sorting), so that the user could double click it and go up one level...
I'd like to display folders and then files (just like Windows explorer does) regardless of the sorting.I'm currently using the following code to initialize the model and the view:
self.model = QFileSystemModel()
self.model.setRootPath(path)
self.model.setFilter(QDir.NoDot | QDir.AllEntries)
self.model.sort(0,Qt.SortOrder.AscendingOrder)
self.ui.treeView.setModel(self.model)
self.ui.treeView.setRootIndex(self.model.index(path))
self.ui.treeView.header().setSortIndicator(0, Qt.AscendingOrder)
self.ui.treeView.setSortingEnabled(True)
Instead of QFileSystemModel() I'm actually using my customized QFileSystemModel with an additional column.
The problems I'm experiencing are that:
..
gets sorted together with other contents and doesn't appear at the topI don't understand what's the best approach for the problems I'm solving.
I see the following options:
..
to be always on top regardless the sorting (not sure if it's possible) and also keep directories first (there's a related question), I could also potentially use it for the point 3 above to display the files by certain criteria..
always on top seems to cause troubles in any case)...
at the top of QTreeView after it's loaded or sortedI tried implementing QSortFilterProxyModel, but ran into another problem: I don't understand how I should modify treeView.setRootIndex()
call.
So my specific questions are:
The following solution works:
class SortingModel(QSortFilterProxyModel):
def lessThan(self, source_left: QModelIndex, source_right: QModelIndex):
file_info1 = self.sourceModel().fileInfo(source_left)
file_info2 = self.sourceModel().fileInfo(source_right)
if file_info1.fileName() == "..":
return self.sortOrder() == Qt.SortOrder.AscendingOrder
if file_info2.fileName() == "..":
return self.sortOrder() == Qt.SortOrder.DescendingOrder
if (file_info1.isDir() and file_info2.isDir()) or (file_info1.isFile() and file_info2.isFile()):
return super().lessThan(source_left, source_right)
return file_info1.isDir() and self.sortOrder() == Qt.SortOrder.AscendingOrder
The code for initializing view and model are the same as in @bartolo-otrit answer:
model = QFileSystemModel()
model.setRootPath('.')
model.setFilter(QDir.NoDot | QDir.AllEntries)
model.sort(0, Qt.SortOrder.AscendingOrder)
sorting_model = SortingModel()
sorting_model.setSourceModel(model)
view.tree_view.setModel(sorting_model)
view.tree_view.setRootIndex(sorting_model.mapFromSource(model.index('.')))
view.tree_view.header().setSortIndicator(0, Qt.AscendingOrder)
view.tree_view.setSortingEnabled(True)