如何将 QDesktopServices::openUrl 与包含“#”的 'file:' URL 一起使用?

How do I use QDesktopServices::openUrl with 'file:' URL containing '#'?

在我的应用程序中,我生成了一个 HTML 文件,我想通过单击按钮打开该文件。 所以我的文件被命名为,例如:

QString file = "F:/the_path/to_the_/generated_html_file.html";

在 Windows 我将其更改为:

file = "file:///F:/the_path/to_the_/generated_html_file.html";

这样我就可以用 :

打开它
QDesktopServices::openUrl(QUrl(file));

它会在默认浏览器中打开。

但是当字符 # 出现在路径或文件名中时,它不再起作用并且 URL 似乎在 # 之后被截断了.

例如,如果我将文件命名为 generated#_html_file.html,我会收到此错误消息:

ShellExecute 'F:/the_path/to_the_/generated' failed (error 2).

为什么会发生这种情况,我该如何避免?

在 URL 中,# 是分隔 'fragment identifier' 与资源位置的字符。要使用文字 # 引用 file: URL,需要对其进行转义(如 %23)。

参考:RFC 1738:

The character "#" is unsafe and should always be encoded because it is used in World Wide Web and in other systems to delimit a URL from a fragment/anchor identifier that might follow it.

SteveTJS 所述,静态方法 QUrl::fromLocalFile() 是为此目的提供的,因此您可以编写

QDesktopServices::openUrl(QUrl::fromLocalFile(file));

而不是

QDesktopServices::openUrl(QUrl(file));

这将

  1. 添加 file: 协议标识符和 // 空主机名
  2. 将本机路径分隔符转换为 /(如果不同)
  3. 对 URL 的所有非安全字符进行编码。

我刚找到解决方案:

QString file = "F:/the_path/to_the_/generated#_html_file.html";
QUrl url = QUrl::fromLocalFile(file);
// gives url="file:///F:/the_path/to_the_/generated%23_html_file.html";
QDesktopServices::openUrl(url); //works