1

In PyQt5 there exists QtWidgets.QFileDialog() which allow user to chose file from disc. I would like to have files sorted by date ascending in this window at entering (it is possible with user action). As I've been looking by web i found issues (1, 2) around topic, but still I cannot achieve that. It seems that QFileDialog does not have this option as common one, but it could be done with setting properly ProxyModel with setProxyModel(). I did it and it seems to have no effect, how sorting by date can be achieved?

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_())

QFileDialog sort by name

===edit===

This function sorts files ascending, but only by name - it is not possible to select column.

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
General Grievance
  • 4,555
  • 31
  • 31
  • 45
  • (1) Changes to an instance of QFileDialog will never be reflected in the internal dialogs shown via the static functions. (2) Calling `sort` *before* setting the proxy will obviously have no effect. (3) The date column has index 3, not 2. – ekhumoro Oct 09 '22 at 13:08
  • Is it possible to pass sort model as argument to getOpenFileName? Or maybe to create PyQt5 native save/load dialog in other way that allow to choose sorting options? – Jakub Aniulis Oct 09 '22 at 19:59
  • No. Just use the `dialog` you already created. – ekhumoro Oct 09 '22 at 20:46
  • Code with suggested changes is uploaded. QFileDialog is called with exec_() so dialog settings is applied. Sort is called in every way I could think of. Still there is something missing and sorting by date is not achieved. How should I call sorting? Or maybe ProxyModel is created in wrong way? – Jakub Aniulis Oct 10 '22 at 07:33
  • Actually solution with thread function changes sorting order (it is ascending) but only with name column, it is not possible to select sorting column. – Jakub Aniulis Oct 10 '22 at 07:40
  • Using threading is totally pointless and wrong. You are still calling `sort()` ***before*** setting the proxy, which obviously cannot work since there's no data to sort at that point. You should also note that the default sorting method is just a simple *textual* sort (if you switch to Detail View, you will see that the built-in behaviour is exactly the same). To get more sophisticated sorting, you must [implement it yourself](https://doc.qt.io/qt-5/qsortfilterproxymodel.html#lessThan) (e.g. by converting the text values to date objects). – ekhumoro Oct 10 '22 at 13:01

0 Answers0