QFileDialog 将 MIME 类型过滤器结合到“所有格式”

Cyb*_*ran 3 c++ qt openfiledialog mime-types

我正在使用 Qt 5.9 打开一个文件对话框,要求用户选择一个图像文件:

QStringList mimeTypeFilters;
const QByteArrayList supportedMimeTypes = QImageReader::supportedMimeTypes();
foreach(const QByteArray& mimeTypeName, supportedMimeTypes) {
    mimeTypeFilters.append(mimeTypeName);
}
mimeTypeFilters.sort();

QFileDialog* fileDialog = new QFileDialog(this, "Select image");
fileDialog->setMimeTypeFilters(mimeTypeFilters);
fileDialog->setFileMode(QFileDialog::ExistingFile);
fileDialog->exec();
Run Code Online (Sandbox Code Playgroud)

所有支持的图像格式都作为 MIME 类型过滤器添加到对话框中,效果非常好。但是,我想添加一个额外的过滤器(例如“所有格式”或“所有支持的”),允许用户选择任何受支持格式的图像,因为在选择图像之前选择正确的格式非常繁琐。实现此目的的最优雅的解决方案是什么,而不需要子类化任何涉及的 Qt 类?

Cyb*_*ran 7

感谢 SteakOverflow 的评论,这是我想出的解决方案:

// get supported image file types
QStringList mimeTypeFilters;
const QByteArrayList supportedMimeTypes = QImageReader::supportedMimeTypes();
foreach(const QByteArray& mimeTypeName, supportedMimeTypes) {
    mimeTypeFilters.append(mimeTypeName);
}
mimeTypeFilters.sort(Qt::CaseInsensitive);

// compose filter for all supported types
QMimeDatabase mimeDB;
QStringList allSupportedFormats;
for(const QString& mimeTypeFilter: mimeTypeFilters) {
    QMimeType mimeType = mimeDB.mimeTypeForName(mimeTypeFilter);
    if(mimeType.isValid()) {
        allSupportedFormats.append(mimeType.globPatterns());
    }
}
QString allSupportedFormatsFilter = QString("All supported formats (%1)").arg(allSupportedFormats.join(' '));

QFileDialog* fileDialog = new QFileDialog(this, "Select image");
fileDialog->setFileMode(QFileDialog::ExistingFile);
fileDialog->setMimeTypeFilters(mimeTypeFilters);
QStringList nameFilters = fileDialog->nameFilters();
nameFilters.append(allSupportedFormatsFilter);
fileDialog->setNameFilters(nameFilters);
fileDialog->selectNameFilter(allSupportedFormatsFilter);
Run Code Online (Sandbox Code Playgroud)

它与 QFileDialog 内部使用的将 mime 类型过滤器转换为名称过滤器的实现基本相同。所有支持格式的新名称过滤器将添加到过滤器列表的底部并预先选择。过滤器字符串相当长,并且不能立即在对话框中完全可见,但一旦用户打开下拉菜单,就会完全可见。