I want to show only mounted drives sorted by drive letter in windows using Qt 5.10. Here is my test code:
#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();
}
This works fine, producing this output, except it is not sorted by drive letter:
Running the same code, but setting the treeview model as
tree.setModel(fsModel); // use QFileSystemModel, not QSortFilterProxyModel
results in the following, where the items are sorting the way I want:
I thought this might be a role issue. Here is the output from my qDebug statements:
QFileSystemModel::FilePathRole = "C:/" Qt::DisplayRole = "C:"
QFileSystemModel::FilePathRole = "D:/" Qt::DisplayRole = "Data (D:)"
QFileSystemModel::FilePathRole = "E:/" Qt::DisplayRole = "Photos (E:)"
QFileSystemModel::FilePathRole = "F:/" Qt::DisplayRole = "Archive (F:)"
QFileSystemModel::FilePathRole = "H:/" Qt::DisplayRole = "Old D (H:)"
QFileSystemModel::FilePathRole = "I:/" Qt::DisplayRole = "Old C (I:)"
So I included this line
fsFilter->setFilterRole(QFileSystemModel::FilePathRole);
but this did not help.
Solution (corrected in code listing above):
fsFilter->setSortRole(QFileSystemModel::FilePathRole);