Введение
Текстовые описания сложных, многошаговых интерфейсных операций (например, настройка сложного фильтра в графическом редакторе) часто менее понятны, чем короткое видео или анимированный GIF, показывающий процесс наглядно. В статье рассмотрим, как встраивать видео и анимации в HTML-страницы справки, и какие ограничения накладывает выбор между QTextBrowser и QWebEngineView как движком отображения контента.
Концепция
QTextBrowser, основанный на ограниченном подмножестве HTML/CSS (статья 165), не поддерживает тег <video> и воспроизведение видео вообще — он способен отображать только статичные изображения, включая анимированные GIF (которые он действительно умеет проигрывать, поскольку анимация GIF реализована на уровне формата изображения, а не через видео-теги). Для настоящего видео внутри встроенной справки нужен QWebEngineView, который поддерживает HTML5 <video> через тот же движок Chromium, что используется и для остальной отрисовки страниц.
Пример кода: Видео и анимированные
<!-- documents.html — страница справки с анимированным GIF, работающим даже в QTextBrowser -->
<h2 id="filter-setup">Настройка фильтра изображения</h2>
<p>
Следующая анимация показывает процесс настройки фильтра размытия шаг за шагом:
</p>
<img src="qthelp://com.mycompany.myapp.1.0/doc/images/filter_demo.gif"
alt="Демонстрация настройки фильтра"
width="480" />
<p>
Если анимация выше не отображается, ознакомьтесь с
<a href="#filter-setup-text">текстовым описанием</a> того же процесса.
</p>
<!-- Тот же раздел, но с настоящим видео — требует QWebEngineView -->
<h2 id="filter-setup">Настройка фильтра изображения</h2>
<video width="480" controls>
<source src="qthelp://com.mycompany.myapp.1.0/doc/videos/filter_demo.mp4" type="video/mp4">
Ваш браузер справки не поддерживает воспроизведение видео.
Смотрите GIF-версию ниже.
</video>
// Расширение HelpBrowser (из статьи 165) для определения MIME-типа видеофайлов
QVariant HelpBrowser::loadResource(int type, const QUrl &url)
{
if (url.scheme() == "qthelp") {
return QVariant(m_helpEngine->fileData(url));
}
return QTextBrowser::loadResource(type, url);
}
// Для QWebEngineView нужно расширить QtHelpUrlSchemeHandler (статья 172)
// корректным определением MIME-типа на основе расширения файла
QString detectMimeType(const QString &path)
{
if (path.endsWith(".mp4")) return "video/mp4";
if (path.endsWith(".webm")) return "video/webm";
if (path.endsWith(".gif")) return "image/gif";
if (path.endsWith(".png")) return "image/png";
return "text/html";
}
<!-- Добавление медиафайлов в .qhp -->
<files>
<file>source/documents.html</file>
<file>images/filter_demo.gif</file>
<file>videos/filter_demo.mp4</file>
</files>
Пояснения к коду
Первый вариант HTML использует анимированный GIF — он работает одинаково в QTextBrowser и QWebEngineView, поскольку GIF — это просто формат изображения с встроенной анимацией кадров, не требующий поддержки видео-тегов или JavaScript. Текстовая альтернатива через ссылку #filter-setup-text — хорошая практика на случай, если по какой-то причине анимация не отображается (например, если в будущем справка будет открываться неким третьим инструментом с ограниченной поддержкой изображений).
Второй вариант с настоящим <video> принципиально требует QWebEngineView — detectMimeType() показывает необходимое расширение обработчика схемы qthelp:// (из статьи 172) для возврата корректного MIME-типа видеофайла, без которого браузер не поймёт, как интерпретировать байты, возвращённые из fileData(), и не запустит воспроизведение.
Подводные камни
- Видеофайлы значительно увеличивают размер .qch и общий объём дистрибутива приложения. В отличие от текста и небольших изображений, видео даже умеренного качества может весить десятки мегабайт — для продуктов с очень компактным базовым дистрибутивом стоит рассмотреть хранение видео отдельно от основного .qch (например, в отдельном ресурсном пакете, подключаемом по требованию, а не встроенном в основной установочный файл).
QTextBrowser, не имеющий поддержки<video>, просто молча игнорирует тег без вывода ошибки или текста-заглушки внутри<video>...</video>(текст-заглушка в HTML5-видео показывается только в браузерах, действительно не поддерживающих формат, но интерпретирующих сам тег<video>—QTextBrowserне делает даже этого) — если справка должна одновременно поддерживать оба движка отображения (например, для разных версий приложения), нужно явно проектировать страницы с GIF как основным вариантом и видео — опционально, через JavaScript-определение поддержки, а не полагаться на фоллбэк внутри самого HTML5-тега.- Большие GIF-файлы с высоким разрешением и частотой кадров могут весить даже больше, чем сравнимое по длительности видео в современном кодеке (H.264) — для длинных демонстраций (больше 10-15 секунд) настоящее видео почти всегда эффективнее по объёму, чем GIF, и выбор GIF оправдан в первую очередь совместимостью с
QTextBrowser, а не эффективностью сжатия. - Автовоспроизведение видео (
autoplay) внутри справки без явного намерения пользователя может быть навязчивым и неожиданным опытом, особенно если у пользователя включён звук — атрибутcontrolsбезautoplay(как в примере) — более уважительный к пользователю выбор по умолчанию, оставляющий запуск воспроизведения на явное действие.