如何将自定义项目添加到QFileDialog?
  我正在使用非本地QFileDialog (用于选择目录路径),我需要添加一些自定义驱动器。  我甚至不需要在这些驱动器中显示任何内容,我只需要在顶层显示这些驱动器(最好是使用我的图标),并在用户选择它时在结果中输出一些特殊的字符串。 

实现这个最简单的方法是什么?
我已经阅读过可以使用代理模型的文档,但我不明白如何实现这种模型,所有示例仅显示对已有项目进行过滤和排序。
如果我理解正确,你想添加额外的驱动器到文件对话框左侧的侧栏上?
  你正在寻找的功能是QFileDialog::setSidebarUrls 
#include <QApplication>
#include <QMainWindow>
#include <QHBoxLayout>
#include <QPushButton>
#include <QFileDialog>
int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    QMainWindow window;
    QWidget widget;
    QHBoxLayout layout(&widget);
    QPushButton open("open");
    layout.addWidget(&open);
    QObject::connect(&open, &QPushButton::clicked, [&]()
        {
            QFileDialog dialog;
            dialog.setOption(QFileDialog::DontUseNativeDialog);
            QList<QUrl> drives;
            drives << QUrl::fromLocalFile(QDir("D:").absolutePath());
            drives << QUrl::fromLocalFile(QDir("E:").absolutePath());
            drives << QUrl::fromLocalFile(QDir("foobar").absolutePath());
            dialog.setSidebarUrls(drives);
            dialog.exec();
        });
    window.setCentralWidget(&widget);
    window.show();
    return app.exec();
}
结果如下所示:

但是,如果您添加的驱动器不存在/无法访问,则它们将显示为灰色。
一般信息
  你是对的,你需要设置一个代理模型。  基本上你的任务是用QAbstractProxyModel添加一行。  这比删除行要困难得多。 
  如果我们看一下QFileDialog::setProxyModel的源代码,我们发现这个: 
proxyModel->setParent(this);
d->proxyModel = proxyModel;
proxyModel->setSourceModel(d->model);
  由此我们知道QFileDialog有一个自动设置为代理模型源的内部模型。  查看私有头文件,我们发现源模型的类型是QFileSystemModel 。  因此,我们可以期望我们的代理模型需要能够提供与源模型相同的角色。  该文档具有它们的列表: FileIconRole , FileNameRole , FilePathRole , FilePermissionRole 。 
  更糟糕的是, QFileDialog有时会调用proxyModel.mapToSource()和proxyModel.mapFromSource()来访问源索引。  因为我们要添加一行,所以我们的新索引没有相应的源索引(在源模型中)。  这意味着我们必须编写我们自己的mapToSource和mapFromSource的实现。 
履行
  我建议从QIdentityProxyModel开始,因为你可以使用可用的方法来处理所有刚刚传递给源模型的索引。 
  我不清楚你需要重新实现多少种方法,以及你可以多久使用QIdentityProxyModel提供的QIdentityProxyModel 。  从简单的东西开始: 
int MyDriveProxyModel::rowCount(const QModelIndex &parent = QModelIndex()) const {
    if (parent.isValid()) {
        return QIdentityProxyModel::rowCount(parent);
    } else {
        return QIdentityProxyModel::rowCount(parent) + 1;
    }
}
然后重新实现两种映射方法:
QModelIndex MyDriveProxyModel::mapToSource(const QModelIndex &proxyIndex) const {
    if (this_index_belongs_to_the_added_row) { // there are many ways for this
        return this->createIndex(proxyIndex.row(), proxyIndex.column(), /* some_data */);
    }
    return QIdentityProxyModel::mapToSource(proxyIndex);
}
QModelIndex MyDriveProxyModel::mapFromSource(const QModelIndex &proxyIndex) const {
    ...
}
  一旦这个工作,你需要以类似的方式至少实现QAbstractItemModel::data和QAbstractItemModel::flags 。 
结论
它应该是可行的,但是在犯错误很容易的地方是相当多的工作。 Qt真正需要的是一种将多个模型合并为一个的方法,但我还没有看到过这样的类,因此您必须这样做。
链接地址: http://www.djcxy.com/p/96515.html