Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort filenames naturally with Qt

I am reading a directories content using QDir::entryList(). The filenames within are structured like this:

index_randomNumber.png

I need them sorted by index, the way the Windows Explorer would sort the files so that I get

0_0815.png
1_4711.png
2_2063.png
...

instead of what the sorting by QDir::Name gives me:

0_0815.png
10000_6661.png
10001_7401.png
...

Is there a built-in way in Qt to achieve this and if not, what's the right place to implement it?

like image 708
Herr von Wurst Avatar asked Aug 13 '12 11:08

Herr von Wurst


3 Answers

If you want to use QCollator to sort entries from the list of entries returned by QDir::entryList, you can sort the result with std::sort():

dir.setFilter(QDir::Files | QDir::NoSymLinks);
dir.setSorting(QDir::NoSort);  // will sort manually with std::sort

auto entryList = dir.entryList();

QCollator collator;
collator.setNumericMode(true);

std::sort(
    entryList.begin(),
    entryList.end(),
    [&](const QString &file1, const QString &file2)
    {
        return collator.compare(file1, file2) < 0;
    });

According to The Badger's comment, QCollator can also be used directly as an argument to std::sort, replacing the lambda, so the call to std::sort becomes:

std::sort(entryList.begin(), entryList.end(), collator);
like image 76
Romário Avatar answered Oct 19 '22 12:10

Romário


Qt didn't have natural sort implementation until Qt 5.2, see this feature request.

Since Qt 5.2 there is QCollator which allows natural sort when numeric mode is enabled.

like image 13
scai Avatar answered Oct 19 '22 12:10

scai


Yes it is possible.

In order to do that you need to specify the flag LocaleAware when constructing the QDir. object. The constructor is

 QDir(const QString & path, const QString & nameFilter, SortFlags sort = SortFlags( Name | IgnoreCase ), Filters filters = AllEntries)

You can also use

QDir dir;
dir.setSorting(QDir::LocaleAware);
like image 2
UmNyobe Avatar answered Oct 19 '22 11:10

UmNyobe