Не работает сортировка папок в QFileSystemModel

Попытался включить сортировку в QFileSystemModel путем добавления dirModel->sort(0, Qt::AscendingOrder); не помогло. Пути .. и . оказываются где угодно, то в центре то сверху то снизу. Хотелось бы, чтобы данные пути всегда были сверху.

QString mPath = "/media/usbhd-sda1/";
dirModel = new QFileSystemModel(this);
dirModel->setFilter(QDir::AllEntries);
dirModel->setRootPath(mPath);
dirModel->sort(0, Qt::AscendingOrder);
ui->listView->setModel(dirModel);
ui->listView->setGridSize( QSize( 64, 64) );
ui->listView->setIconSize( QSize( 64, 64 ) );
ui->listView->setUniformItemSizes( true );
ui->listView->setRootIndex(dirModel->index(mPath));
ui->listView_2->setModel(dirModel);
ui->listView_2->setGridSize( QSize( 64, 64) );
ui->listView_2->setIconSize( QSize( 64, 64 ) );
ui->listView_2->setUniformItemSizes( true );

Ответы (1 шт):

Автор решения: Alexander Chernin

Вам надо наследоваться от класса QSortFilterProxyModel и переопределить в нем метод lessThan(). Реализация выглядит так:

class MySort : public QSortFilterProxyModel {
protected:
    bool lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const {
        QString left = sourceModel()->data(source_left).toString();
        QString right = sourceModel()->data(source_right).toString();

        // Если left, или right соответствуют "." и "..", или наоборот
        if( (left == "." && right == "..") || (right == "." && left == "..") ) {
            return false;
        } else if( left == "." || right == "." || left == ".." || right == ".." ) {
            // Любое из значений либо ".", или ".."
            return false;
        }
        return QSortFilterProxyModel::lessThan(source_left, source_right);
    }
}

Тогда объект QListView инициализируется так:

model = new QFileSystemModel(this);
model->setRootPath( rootPath );

//Показывать все директории
model->setFilter(QDir::AllDirs);

MySort* proxy = new MySort();
proxy->setSourceModel(model);
proxy->sort(0, Qt::AscendingOrder); // или Qt::DescendingOrder

// Устанавливаем нашу прокси в качестве модели
ui->listView->setModel(proxy);

// Установка корневой папки отображения

Меняем порядок сортировки в слоте, например, при клике на какую-то кнопку:

void SomeWindow::changeSortOrder() {
    MySort* proxy = qobject_cast<MySort*>(ui->listView->model());

    if( proxy ) {
        Qt::SortOrder order = proxy->sortOrder() == Qt::AscendingOrder? Qt::DescendingOrder: Qt::AscendingOrder;
        proxy->sort(0, order);
    }
}
→ Ссылка