Сортировка файлов и папок в QSortFilterProxyModel

sort, QSortFilterProxyModel, qt

Доброго дня! Есть задача отсортировать данные в директории таким образом, чтобы сначала шли папки в алфавитном порядке, а затем файлы тоже в алфавитном порядке. Данным кодом получается добиться только порядка: сначала папки, потом файлы, но они не по алфавиту идут. Что в этом коде надо поправить, может кто видит..

  1. bool SortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
  2. {
  3. bool isDir = QVariant(sourceModel()->data(left, Roles::IsDirRole).toString()).toBool();
  4.  
  5. QString const leftName = sourceModel()->data(left, Roles::NameRole).toString();
  6. QString const rightName = sourceModel()->data(right, Roles::NameRole).toString();
  7.  
  8. if(isDir)
  9. {
  10. return true;
  11. }
  12. else
  13. {
  14. int const compare = QString::localeAwareCompare(leftName, rightName);
  15. if(compare != 0) {
  16. return compare < 0 && isDir;
  17. }
  18. }
  19.  
  20. return false;
  21. }
2

Do you like it? Share on social networks!

6
Evgenii Legotckoi
  • July 29, 2020, 4:59 p.m.
  • (edited)

Добрый день! А какую исходную модель используете? Случайно не QDirModel ? Просто у неё есть метод setSorting , который при установке некоторых флагов позволит отсортировать как по имени, так и по типу, сначала директории, а потом файлы и наоборот. И использование QSortFilterProxyModel будет избыточна. Просто в Qt для подобного функционала уже всё реализовано.

    Вообще исходной является QAbstractTableModel. Само отображение происходит в QML. Изначально, когда это делалось про сортировку никто видимо не подумал, поэтому потом пришлось навернуть еще QSortFilterProxyModel поверх..
    Отображение в QML:

    1. model: SortFilterProxyModel {
    2. source: FileBrowserModel
    3. sortOrder: Qt.AscendingOrder
    4. sortCaseSensitivity: Qt.CaseInsensitive
    5. }

    Видимо в методе lessThan() сортировать по типу и имени не получится, это ей несколько проходов сделать надо будет.. либо какое-то хитрое условие прописать как сравнивать..

      Evgenii Legotckoi
      • July 29, 2020, 6:06 p.m.
      • (edited)

      Ну тогда так попробуйте. Там нужно делать сравнение по алфавиту лишь в том случае если и левый и правый индекс либо каталоги, либо файлы. Что по сути не делается в вашем коде.

      1. bool SortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
      2. {
      3. bool isLeftDir = QVariant(sourceModel()->data(left, Roles::IsDirRole).toString()).toBool();
      4. bool isRightDir = QVariant(sourceModel()->data(right, Roles::IsDirRole).toString()).toBool();
      5.  
      6. QString const leftName = sourceModel()->data(left, Roles::NameRole).toString();
      7. QString const rightName = sourceModel()->data(right, Roles::NameRole).toString();
      8.  
      9. if ((isLeftDir && isRightDir) || (!isLeftDir && !isRightDir))
      10. {
      11. const int compare = QString::localeAwareCompare(leftName, rightName);
      12. if(compare != 0) {
      13. return compare < 0;
      14. }
      15. }
      16. else if (isLeftDir)
      17. {
      18. return true;
      19. }
      20.  
      21. return false;
      22. }

        Шикарно! Спасибо, то что надо!
        Первый if понятен, а зачем вот эта часть, что-то не пойму..

        1. else if (isLeftDir)
        2. {
        3. return true;
        4. }

          Вам нужно расположить сначала каталоги, а потом файлы. Так же? Поэтому нужно проверить, что левый индекс является каталогом, а правый в данном случае будет считаться файлом, поскольку первый if уже исключил, что оба индекса могут отвечать за каталоги или файлы одновременнов.

            Ясно, спасибо. Работает как нужно

              Comments

              Only authorized users can post comments.
              Please, Log in or Sign up
              • Last comments
              • AK
                April 1, 2025, 11:41 a.m.
                Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
              • Evgenii Legotckoi
                March 9, 2025, 9:02 p.m.
                К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
              • VP
                March 9, 2025, 4:14 p.m.
                Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
              • ИМ
                Nov. 22, 2024, 9:51 p.m.
                Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
              • Evgenii Legotckoi
                Oct. 31, 2024, 11:37 p.m.
                Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup