QFileSystemModel和Proxy在QTreeView中的排序方式不同

时间:2018-03-22 00:03:16

标签: qt qfilesystemmodel qsortfilterproxymodel

我想只显示使用Qt 5.10在Windows中按驱动器号排序的已安装驱动器。这是我的测试代码:

#include <QtWidgets>
#include <QDebug>

QStringList mountedDrives;

class FSFilter : public QSortFilterProxyModel
{
public:
    FSFilter(QObject *parent)  : QSortFilterProxyModel(parent) {}
protected:
    bool filterAcceptsRow(int row, const QModelIndex &par) const override
    {
        QModelIndex idx = sourceModel()->index(row, 0, par);
        QString path = idx.data(QFileSystemModel::FilePathRole).toString();
        QString path2 = idx.data(Qt::DisplayRole).toString();
        bool mounted = mountedDrives.contains(path);
        if (mounted) {
            qDebug() << "QFileSystemModel::FilePathRole =" << path
                     << "  Qt::DisplayRole =" << path2;
            return true;
        }
        else return false;
    }
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    // get mounted drives only
    foreach (const QStorageInfo &storage, QStorageInfo::mountedVolumes()) {
        if (storage.isValid() && storage.isReady()) {
            if (!storage.isReadOnly()) {
                mountedDrives << storage.rootPath();
            }
        }
    }

    QFileSystemModel *fsModel = new QFileSystemModel;
    fsModel->setRootPath("");

    FSFilter *fsFilter = new FSFilter(fsModel);
    fsFilter->setSourceModel(fsModel);
    fsFilter->setSortRole(QFileSystemModel::FilePathRole); // now it works
    fsModel->fetchMore(fsModel->index(0,0));

    QTreeView tree;
    tree.setModel(fsFilter);  // different sort if use  
    tree.setModel(fsFilter);
    tree.setSortingEnabled(true);
    tree.sortByColumn(0, Qt::AscendingOrder);

    tree.resize(800, 400);
    tree.setColumnWidth(0, 300);
    tree.setWindowTitle(QObject::tr("File System Test"));
    tree.show();

    return app.exec();
}

这样可以正常工作,产生此输出,但它没有按驱动器号排序:

Mounted Drives using QSortFilterProxyModelfilter

运行相同的代码,但将树视图模型设置为

tree.setModel(fsModel);  // use QFileSystemModel, not QSortFilterProxyModel

导致以下内容,其中项目按我想要的方式排序: All drives using QFileSystemModel without proxy

我认为这可能是一个角色问题。这是我的qDebug语句的输出:

  

QFileSystemModel :: FilePathRole =&#34; C:/&#34; Qt :: DisplayRole =&#34; C:&#34;

     

QFileSystemModel :: FilePathRole =&#34; D:/&#34; Qt :: DisplayRole =&#34;数据   (d:)&#34;

     

QFileSystemModel :: FilePathRole =&#34; E:/&#34; Qt :: DisplayRole =&#34;照片   (E:)&#34;

     

QFileSystemModel :: FilePathRole =&#34; F:/&#34; Qt :: DisplayRole =   &#34;档案(F :)和#34;

     

QFileSystemModel :: FilePathRole =&#34; H:/&#34; Qt :: DisplayRole =&#34;老D.   (H:)&#34;

     

QFileSystemModel :: FilePathRole =&#34; I:/&#34; Qt :: DisplayRole =&#34;旧C   (I:)&#34;

所以我加入了这一行

fsFilter->setFilterRole(QFileSystemModel::FilePathRole);

但这没有帮助。

解决方案(在上面的代码清单中更正):

fsFilter->setSortRole(QFileSystemModel::FilePathRole);

1 个答案:

答案 0 :(得分:1)

您应该在FSFilter中重新实现虚拟函数lessThan,默认情况下按字母顺序排序,但在这种情况下,您需要考虑驱动器名称中的第一个和最后一个字母。