python - PySide6 上的自定义文件浏览器实现
问题描述
我想在 PySide6 上实现文件浏览器,我的目标是:
- 始终在顶部显示文件和文件夹
..
(无论排序如何),以便用户可以双击它并上一级。 - 在
..
我想显示文件夹然后显示文件(就像 Windows 资源管理器一样)之后,不管排序如何。 - 有一个显示特定文件集的替代显示模式(它们可以位于不同的驱动器、不同的文件夹等)。
我目前正在使用以下代码来初始化模型和视图:
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 并以某种方式强制
..
始终位于顶部,无论排序(不确定是否可能)并且还首先保留目录(有一个相关的问题),我也可以将它用于上面的第 3 点以按某些标准显示文件 - 使用完全不同的方法,可能是我将手动填写的 QFileSystemWatcher 或 QTreeWidget(
..
始终保持在最前面似乎在任何情况下都会造成麻烦)。 - 加载或排序后以某种方式添加
..
到 QTreeView 的顶部
我尝试实现 QSortFilterProxyModel,但遇到了另一个问题:我不明白应该如何修改treeView.setRootIndex()
调用。
所以我的具体问题是:
- 我可以使用 QSortFilterProxyModel 来解决上面提到的所有问题吗?如果是,请提供示例实现。
- 如果您认为有更好的方法来解决这个问题,请描述它。
解决方案
以下解决方案有效:
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)
推荐阅读
- html - Flexbox CSS 中的溢出滚动项右侧没有空间
- javascript - 如何在下拉列表中设置正确的值
- dart - Dart 映射函数作为具有节点互操作的构造函数
- r - R 如何拟合第一个观察点 arima?
- javascript - 如何通过 AJAX 显示来自 MySQL 的 BLOB 图像?
- node.js - 子文件和外部的 Socket.io on('connect)
- python - 逐元素乘法 - 'NoneType' 对象没有属性 '_inbound_nodes'
- oracle11g - 哪一个是执行计划的驱动表?
- observable - 使用 Rx 在 Kotlin 中将 Flowable 转换为 Observable
- javascript - C# 和 Jquery 数据表服务器端处理问题