如何让PyQt5 QFileDialog默认按日期升序排序?
问题
在PyQt5中使用QtWidgets.QFileDialog实现文件选择功能时,希望打开对话框时默认按日期升序排列文件(用户手动操作可实现该排序)。尝试通过QSortFilterProxyModel实现,但未生效;修改后的代码仅能按名称升序排序,无法指定按日期列排序,如何实现按日期排序的需求?
尝试代码
from PyQt5 import QtWidgets, QtCore, QtGui import sys import os def file_name_dialog(extension="All Files (*);;Python Files (*.py)", local_folder="", operation="Open"): options = QtWidgets.QFileDialog.Options() options |= QtWidgets.QFileDialog.DontUseNativeDialog dialog = QtWidgets.QFileDialog() dialog.setOptions(options) local_path = os.getcwd() dialog.setDirectory(local_path+local_folder) sorter = QtCore.QSortFilterProxyModel() #QAbstractProxyModel QFileDialog sort sorter.setDynamicSortFilter(True) sorter.sort(2, QtCore.Qt.SortOrder.AscendingOrder) dialog.setProxyModel(sorter) #doesnt work :( if operation == "Open": file_path, _ = dialog.getOpenFileName(None, local_folder, "", extension, options=options) else: file_path, _ = dialog.getSaveFileName(None, local_folder, "", extension, options=options) if file_path: return file_path else: return None app = QtWidgets.QApplication(sys.argv) myapp = QtWidgets.QMainWindow() myapp.show() file_name_dialog() sys.exit(app.exec_())
编辑后代码
def file_name_dialog(self, extension="All Files (*);;Python Files (*.py)", local_folder="/config", operation="Open"): options = QtWidgets.QFileDialog.Options() options |= QtWidgets.QFileDialog.DontUseNativeDialog dialog = QtWidgets.QFileDialog() dialog.setOptions(options) local_path = os.getcwd() dialog.setDirectory(local_path+local_folder) sorter = QtCore.QSortFilterProxyModel() #QAbstractProxyModel QFileDialog sort dialog.setProxyModel(sorter) sorter.setDynamicSortFilter(True) sorter.sort(3, QtCore.Qt.SortOrder.AscendingOrder) dialog.setProxyModel(sorter) import threading import time def run_task_handler(): time.sleep(0.2) sorter.sort(3, QtCore.Qt.SortOrder.AscendingOrder) dialog.proxyModel().sort(3, QtCore.Qt.SortOrder.AscendingOrder) thread_task_handler = threading.Thread(target=run_task_handler) thread_task_handler.start() #dialog.setFilter(QtCore.QDir(extension).filter()) dialog.setFileMode(QtWidgets.QFileDialog.FileMode.ExistingFile) file_path = False if dialog.exec_(): file_path = dialog.selectedFiles()[0] if file_path: return file_path else: warn("No file chosen") return None
解决方案
问题根源
之前的代码存在两个核心问题:
- 使用
getOpenFileName()/getSaveFileName()这类静态方法时,会重新生成新的对话框实例,之前手动配置的代理模型不会生效。 - 直接调用
sorter.sort()时,对话框的原始模型还未完成初始化,排序指令会被覆盖;且硬编码列索引的方式不可靠,不同平台或Qt版本中日期列的索引可能不同。
正确实现方式
要实现默认按日期排序,需满足以下几点:
- 放弃静态方法,改用
dialog.exec_()手动启动对话框,确保自定义设置生效 - 等待对话框模型初始化完成后再执行排序(用
QTimer延迟执行,避免线程操作的不稳定) - 通过表头文本匹配日期列,替代硬编码索引,提升兼容性
完整代码示例
from PyQt5 import QtWidgets, QtCore, QtGui import sys import os def file_name_dialog(extension="All Files (*);;Python Files (*.py)", local_folder="", operation="Open"): options = QtWidgets.QFileDialog.Options() options |= QtWidgets.QFileDialog.DontUseNativeDialog dialog = QtWidgets.QFileDialog() dialog.setOptions(options) dialog.setDirectory(os.path.join(os.getcwd(), local_folder)) # 设置文件模式与过滤器 if operation == "Open": dialog.setFileMode(QtWidgets.QFileDialog.ExistingFile) else: dialog.setFileMode(QtWidgets.QFileDialog.AnyFile) dialog.setNameFilter(extension) # 配置排序代理模型 sorter = QtCore.QSortFilterProxyModel() sorter.setDynamicSortFilter(True) dialog.setProxyModel(sorter) # 延迟执行排序,确保模型与表头初始化完成 def sort_by_date(): header = dialog.findChild(QtWidgets.QHeaderView) if header: # 通过表头文本匹配日期列,适配不同环境 for col in range(header.count()): if header.model().headerData(col, QtCore.Qt.Horizontal) == "Date Modified": sorter.sort(col, QtCore.Qt.AscendingOrder) break else: # 找不到表头时的 fallback 方案,根据实际情况调整索引 sorter.sort(3, QtCore.Qt.AscendingOrder) QtCore.QTimer.singleShot(100, sort_by_date) # 启动对话框并获取结果 file_path = None if dialog.exec_(): file_path = dialog.selectedFiles()[0] return file_path if file_path else None if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) file_name_dialog() sys.exit(app.exec_())
代码说明
- 规避静态方法:用
dialog.exec_()替代静态方法,确保代理模型等自定义配置能作用到当前对话框实例。 - 延迟排序逻辑:通过
QTimer.singleShot()延迟100ms执行排序,等待对话框内部模型和表头完全初始化,避免排序指令被覆盖。 - 兼容式列索引获取:通过表头文本"Date Modified"定位日期列,比硬编码索引更适配不同平台和Qt版本。
- 动态排序更新:开启
setDynamicSortFilter(True),保证文件夹内文件变动时排序结果自动更新。
内容的提问来源于stack exchange,提问作者Jakub Aniulis
相关产品推荐
相关产品推荐

