Как мне использовать 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));
Это будет
- Подготовьте
file:
идентификатор протокола и//
пустое имя хоста - Преобразовать собственный разделитель пути в
/
(если отличается) - Кодировать любые небезопасные символы для 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