Как использовать QDesktopServices::openUrl с 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).

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


person SteveTJS    schedule 22.07.2015    source источник


Ответы (2)


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

Ссылка: RFC 1738:

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

Как заметил SteveTJS, для этой цели предусмотрен статический метод QUrl::fromLocalFile(), поэтому вы можете написать

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

вместо

QDesktopServices::openUrl(QUrl(file));

Это будет

  1. Добавьте file: идентификатор протокола и // пустое имя хоста.
  2. Преобразовать родной разделитель пути в / (если отличается)
  3. Кодируйте любые небезопасные символы для URL.
person Toby Speight    schedule 22.07.2015
comment
Действительно, я отправил свой ответ в то же время. Функция QUrl::fromLocalFile(...) выполняет свою работу. - person SteveTJS; 22.07.2015
comment
@ Стив - совершенно верно, я не очень часто использую QUrl, поэтому я забыл об этом. Я проголосовал за ваш ответ и добавлю примечание к моему. - person Toby Speight; 22.07.2015

Я только что нашел решение:

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
person SteveTJS    schedule 22.07.2015
comment
Ах да - fromLocalFile() существует именно для такого преобразования. А копия QUrl(url) не нужна? - person Toby Speight; 22.07.2015
comment
@TobySpeight Нет необходимости в QUrl (url), так как параметр url уже подходит. - person SteveTJS; 22.07.2015