C++ 是否有一种方法可以在Linux上使用QFileDialog自动向文件添加扩展名
我希望用户能够为将保存为xml文件的文件输入名称。当前在Windows和Mac上,如果您输入“test”作为文件名,它将自动添加“.xml”,这正是我想要的。不幸的是,在测试Linux构建时,我发现输入不带扩展名的文件名会保存为普通文件。用户必须在文件字符串(即“test.xml”)中指定扩展名,以便以正确的格式保存 下面是我正在使用的代码。这是一个Qt错误还是有办法在Qt中指定如果找不到扩展就应该添加扩展C++ 是否有一种方法可以在Linux上使用QFileDialog自动向文件添加扩展名,c++,qt,qfiledialog,C++,Qt,Qfiledialog,我希望用户能够为将保存为xml文件的文件输入名称。当前在Windows和Mac上,如果您输入“test”作为文件名,它将自动添加“.xml”,这正是我想要的。不幸的是,在测试Linux构建时,我发现输入不带扩展名的文件名会保存为普通文件。用户必须在文件字符串(即“test.xml”)中指定扩展名,以便以正确的格式保存 下面是我正在使用的代码。这是一个Qt错误还是有办法在Qt中指定如果找不到扩展就应该添加扩展 // Get value for "dir". If the setting doesn
// Get value for "dir". If the setting doesn't exist then use
// the the path in "defaultsave.directory"
QString prevPath = prevValues.value("dir", QString::fromStdString(
ConfigService::Instance().getString("defaultsave.directory"))).toString();
QString filter;
filter.append("Files (*.xml)");
filter += ";;AllFiles (*.*)";
QString groupingFile = QFileDialog::getSaveFileName(this, "Save Grouping file as", prevPath, filter);
由于您是从带有getSaveFileName
的对话框中获取字符串的,因此您可以执行以下操作:
if (!groupingFile.endsWith(".xml"))
groupingFile += ".xml";
在Linux上可能有所不同,因为以下文档中包含了一个小片段:
在Windows、Mac OS X和Symbian ^3上,此静态函数将使用本机文件对话框,而不是QFileDialog
换句话说,添加前缀(由本机对话框完成)是异常的,至少在Qt方面是如此
正如评论中指出的那样,您可能会发现此解决方案存在一个问题,即如果您手动键入
xyzy
,并且文件xyzy.xml
已经存在,对话框本身不会通知您(假设本机对话框执行此操作-我实际上没有选中)。如果您想要这种行为,您还需要实现它。我们创建了自己的保存对话框方法来解决这个问题。该解决方案本质上与@paxdiablo的答案相同(只需添加扩展),但更一般:
QString ShowSaveFileDialog(QWidget *parent,
const QString &title,
const QString &directory,
const QString &filter) {
#if defined(Q_WS_WIN) || defined(Q_WS_MAC)
return QFileDialog::getSaveFileName(parent,
title,
directory,
filter);
#else
QFileDialog dialog(parent, title, directory, filter);
if (parent) {
dialog.setWindowModality(Qt::WindowModal);
}
QRegExp filter_regex(QLatin1String("(?:^\\*\\.(?!.*\\()|\\(\\*\\.)(\\w+)"));
QStringList filters = filter.split(QLatin1String(";;"));
if (!filters.isEmpty()) {
dialog.setNameFilter(filters.first());
if (filter_regex.indexIn(filters.first()) != -1) {
dialog.setDefaultSuffix(filter_regex.cap(1));
}
}
dialog.setAcceptMode(QFileDialog::AcceptSave);
if (dialog.exec() == QDialog::Accepted) {
QString file_name = dialog.selectedFiles().first();
QFileInfo info(file_name);
if (info.suffix().isEmpty() && !dialog.selectedNameFilter().isEmpty()) {
if (filter_regex.indexIn(dialog.selectedNameFilter()) != -1) {
QString extension = filter_regex.cap(1);
file_name += QLatin1String(".") + extension;
}
}
return file_name;
} else {
return QString();
}
#endif // Q_WS_MAC || Q_WS_WIN
}
你看过QFileDialog::setDefaultSuffix了吗?你已经考虑过关于平台细节的文档了吗?我已经在最初请求此功能的bug报告中添加了一条注释(并声称已修复):可能与@vsz重复,你是否检查过建议的解决方案是否适用于此处使用的静态调用,
getSaveFileName
?我知道它适用于实际的QFileDialog
对象,我只是不确定静态函数是否有效,因为它们显然并不总是使用QFileDialog
。我忙于让QFileDialog工作,忘了看明显的解决方案。谢谢我仍然想知道为什么QFileDialog的功能对于Linux版本是不同的。@RobertWhitley,看我的更新,有一点文档说明这些静态函数实际上不使用QFileDialog
。这种方法有一个缺点:如果使用QFileDialog::confirmOverwrite
(默认值),QFileDialog测试的文件名与实际写入的文件名不同。解决方案是传递QFileDialog::DontConfigOverwrite
并执行您自己的确认对话框,或者使用QFileDialog::defaultSuffix
,这在QFileDialog::getSaveFileName
中不可用。无论哪种方式,您都需要比静态函数调用更多的代码:-(-1:此重复问题的原件提供了正确答案。此答案存在未检查正确文件的问题overwriting@vsz,我会怎么想?我会认为内存泄漏在长时间运行的程序中是一个bug,但在短时间运行的程序中却与之无关。就像在“上下文问题”中一样但是,我在回答中注意到这是人们可能要考虑的问题。如果你认为它可以改进,我很高兴(和自我不够)接受任何建议:-谢谢你的输入到目前为止,我真的很感激。这不支持多个可能的过滤器,是吗?