Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What determines sorting of files in a QFileDialog?

Users open files in our app through a QFileDialog. The order of the filenames is bizarre. What is determining the sorting order, and how can we make it sort by filenames, or otherwise impose our own sorting, perhaps giving it a pointer to our own comparison function?

The documentation and online forums haven't been helpful. Unless it's well hidden, there doesn't seem to be any sorting method, property, etc.

This is a primarily Linux app, but also runs on Macs. (I know nothing about Mac.)

Here is the juicy part of the source code:

QtFileDialog chooser(parent, caption, directory, filter);
/// QtFileDialog is our class derived from QFileDialog

chooser.setModal(true);
chooser.setAcceptMode(acceptMode);
chooser.setFileMode(fileMode);

QStringList hist = chooser.history();
chooser.setHistory(hist);

/* point "x" */

if(chooser.exec()) {    
    QStringList files = chooser.selectedFiles();
    ...blah blah blah...

From one of the answers, I tried an evil experiment, adding this ill-informed guesswork code at "point x":

QSortFilterProxyModel *sorter = new QSortFilterProxyModel();
sorter->sort(1);  // ???
chooser.setProxyModel(sorter);

But this crashed spectacularly at a point about 33 subroutine calls deep from this level of code. I admit, even after reading the Qt4 documentation and sample code, I have no idea of the proper usage of QSortFilterProxyModel.

like image 717
DarenW Avatar asked Sep 01 '10 20:09

DarenW


2 Answers

I think what you need to do is create a QSortFilterProxyModel which you then set in your QFileDialog with QFileDialog::setProxyModel(QAbstractProxyModel * proxyModel)

Here are some relevant links to the Qt 4.6 docs about it.

http://doc.trolltech.com/4.6/qfiledialog.html#setProxyModel

http://doc.trolltech.com/4.6/qsortfilterproxymodel.html#details

like image 37
Grant Lammi Avatar answered Oct 13 '22 04:10

Grant Lammi


Are you using QFileDialog by calling exec()? If you are, you should have a button to switch the view to Detail View. This will give you some column headers that you can click on to sort the files. It should remember that mode the next time the dialog opens but you can force it by calling setViewMode(QFileDialog::Detail) before calling exec().

An alternative is to call the static function QFileDialog::getOpenFileName() which will open a file dialog that is native to the OS on which you are running. Your users may like the familiarity of this option better.

Update 1:

About sort order in screen cap from OP: alt text

This screen capture is actually showing a sorted list. I don't know if the listing behaviour is originating from the Qt dialog or the underlying file system but I know Windows XP and later do it this way.

When sorting filenames with embedded numbers, any runs of consecutive digits are treated as a single number. With the more classic plain string sorting, files would be sorted like this:

A_A_10e0
A_A_9a05

Going character by character, the first 1 sorts before the 9.

.. But with numerical interpretation (as in Windows 7 at least), they are sorted as:

A_A_9a05
A_A_10e0

The 9 sorts before the 10.

So, the sorting you are seeing is alphabetical with numerical interpretation and not just straight character by character. Some deep digging may be required to see if that is Qt behaviour or OS behaviour and whether or not it can be configured.

Update 2:

The QSortFilterProxyModel will sort the strings alphabetically by default so there is not much work to using it to get the behavior you are looking for. Use the following code where you have "point x" in your example.. (you almost had it :)

QSortFilterProxyModel *sorter = new QSortFilterProxyModel();
sorter->setDynamicSortFilter(true); // This ensures the proxy will resort when the model changes
chooser.setProxyModel(sorter);
like image 181
Arnold Spence Avatar answered Oct 13 '22 02:10

Arnold Spence