首页 > 解决方案 > PySide6 上的自定义文件浏览器实现

问题描述

我想在 PySide6 上实现文件浏览器,我的目标是:

  1. 始终在顶部显示文件和文件夹..(无论排序如何),以便用户可以双击它并上一级。
  2. ..我想显示文件夹然后显示文件(就像 Windows 资源管理器一样)之后,不管排序如何。
  3. 有一个显示特定文件集的替代显示模式(它们可以位于不同的驱动器、不同的文件夹等)。

我目前正在使用以下代码来初始化模型和视图:

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)

而不是 QFileSystemModel() 我实际上使用的是我的自定义 QFileSystemModel 和一个附加列。

我遇到的问题是:

我不明白我正在解决的问题的最佳方法是什么。

我看到以下选项:

我尝试实现 QSortFilterProxyModel,但遇到了另一个问题:我不明白应该如何修改treeView.setRootIndex()调用。

所以我的具体问题是:

  1. 我可以使用 QSortFilterProxyModel 来解决上面提到的所有问题吗?如果是,请提供示例实现。
  2. 如果您认为有更好的方法来解决这个问题,请描述它。

标签: pythonqtreeviewqfilesystemmodelpyside6

解决方案


以下解决方案有效:

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

初始化视图和模型的代码与@bartolo-otrit 答案中的代码相同:

    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)

推荐阅读