Sorting elements based on file name length and integer sequences in QT C++

209 Views Asked by At

I am trying to sort the file names using qtsringlist(). However, I am not sure about how to use normalsorting in QT. The outputs give me something like

"image1.png" "image10.png" "image100.png"

instead of "image1.png" follows by "image2.png" and so on. Then, I add the list into the list widget. Below I have attached my code. QStringList faList; (initialized at header file)

Please help. Thanks.

void QtWidgetsApplication::displayImagesList() {
    QListWidgetItem *item = new QListWidgetItem();
    QDirIterator it(QStringLiteral("C:\\Users\\Documents\\Visual Studio 2015\\Projects\\cas\\images"),
        QStringList() << "*.png", QDir::Files, QDirIterator::Subdirectories);
    QFileInfo files;
    while (it.hasNext()) {
        QFileInfo file(it.next());
        faList.append(file.fileName());
        
        ui.images->setSortingEnabled(true);
    
        //ui.images->sortItems(Qt::AscendingOrder);
        _files.push_back(file.fileName());

        //cout << file.fileName().toStdString() << "\n";
        //Cout << file.fileName().length() << "\n";


        //if (file.fileName().length() == 17) {
        //  cout << file.fileName().toStdString() << "\n";
        //  
        //}

    }
    ui.images->addItems(faList);
    ui.images->setMinimumWidth(ui.images->sizeHintForColumn(0));
}
2

There are 2 best solutions below

2
Vlad Feinstein On

You can't sort strings based on some numeric suffix they have.

The easiest way is to rename your images so that numeric part is zero-padded: image001.png, ... image100.png then the regular sort will work.

Alternatively, you can provide your own compare function that will parse the file name into text part and numeric part and compare them as you like.

2
G.M. On

If you need the items to be sorted in 'natural' order you can use QCollator and make use of its numeric mode.

Example code (untested)...

auto strings = QStringList{}
  << "image_3.png"
  << "image_1.png"
  << "image_4.png"
  << "image_7.png"
  << "image_2.png"
  << "image_10.png"
  << "image_5.png"
  << "image_0.png"
  << "image_8.png"
  << "image_6.png"
  << "image_9.png"
  ;
QCollator col;
col.setNumericMode(true);
std::sort(strings.begin(), strings.end(),
          [&](const QString &a, const QString &b)
            {
              return col.compare(a, b) < 0;
            });