QFileDialog中的过滤

8
我希望能够更具体地过滤在QFileDialog中显示的文件,而不仅仅是通过文件扩展名。我在Qt文档中找到的示例只显示像Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)这样的过滤器。除此之外,我还想为不应该出现在文件对话框中的文件指定一个过滤器,例如XML files (*.xml)但不包括Backup XML files (*.backup.xml)
所以我的问题是,我想在文件对话框中显示一些具有特定文件扩展名的文件,但我不想显示具有特定文件名后缀(并且相同文件扩展名)的其他文件。
例如:
要显示的文件:
file1.xml  
file2.xml

不要显示的文件:

file1.backup.xml  
file2.backup.xml

我想问一下,是否可以为QFileDialog定义这样的过滤器?

3个回答

12

我相信你可以这样做:

  1. 创建一个自定义代理模型。你可以使用QSortFilterProxyModel作为你的模型基类;
  2. 在代理模型中重写filterAcceptsRow方法,并对那些名称中包含 ".backup." 的文件返回 false;
  3. 将新的代理模型设置给文件对话框:QFileDialog::setProxyModel

以下是一个示例:

代理模型:

class FileFilterProxyModel : public QSortFilterProxyModel
{
protected:
    virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const;
};

bool FileFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
    QModelIndex index0 = sourceModel()->index(sourceRow, 0, sourceParent);
    QFileSystemModel* fileModel = qobject_cast<QFileSystemModel*>(sourceModel());
    return fileModel->fileName(index0).indexOf(".backup.") < 0;
    // uncomment to call the default implementation
    //return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
}

对话框是通过这种方式创建的:

QFileDialog dialog;
dialog.setOption(QFileDialog::DontUseNativeDialog);
dialog.setProxyModel(new FileFilterProxyModel);
dialog.setNameFilter("XML (*.xml)");
dialog.exec();

代理模式仅由非本地文件对话框支持。


正如miile7在下面指出的那样,必须在调用setProxyModel()之前调用setOption(QFileDialog::DontUseNativeDialog);。已在Qt 5.11上进行了测试。 - truf

2
@serge_gubenko的解决方案很有效。通过继承QSortFilterProxyModel,创建自己的ProxyModel即可。请保留HTML标签。
class FileFilterProxyModel : public QSortFilterProxyModel
{
protected:
    virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const;
};

bool FileFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
    // Your custom acceptance condition
    return true;
}

请确保在设置代理模型之前设置DontUseNativeDialog(编辑:@serge_gubenkos的答案现在已经这样做了)。原生对话框不支持自定义ProxyModel

QFileDialog dialog;
dialog.setOption(QFileDialog::DontUseNativeDialog);
dialog.setProxyModel(new FileFilterProxyModel);
dialog.setNameFilter("XML (*.xml)");
dialog.exec();

我花了很长时间才找到这个答案。它是在这里写的。


-1

好的,我已经将它与QFileDialog对象一起使用。这只会显示适当目录中列出的文件,很好地选择要处理的文件,例如XML文件、PNG图片等。

下面是我的示例:

 OlFileDialog QFileDialog (this); 
 QString slFileName; 
 olFileDialog.setNameFilter (tr ("Files (* xml)")); 
 olFileDialog.setFileMode (QFileDialog :: anyfile); 
 olFileDialog.setViewMode (QFileDialog :: Detail); 
 if (olFileDialog.exec ()) 
     olFileDialog.selectFile (slFileName); 
 else 
     return; 

对话框只会显示 XML 文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接