Как мне использовать QDesktopServices::openUrl с 'file:' URL, содержащим '#'?

В моем приложении я генерирую 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).

Почему это происходит, и как я могу избежать этого?

2 ответа

Решение

В URL # является символом, который отделяет "идентификатор фрагмента" от местоположения ресурса. Для ссылки file: URL с литералом #, это должно быть экранировано (как %23).

Ссылка: RFC 1738:

Символ "#" небезопасен и всегда должен быть закодирован, поскольку он используется во Всемирной паутине и в других системах для отделения URL-адреса от идентификатора фрагмента / якоря, который может следовать за ним.

Как отмечает 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
Другие вопросы по тегам