Различные статьи по Qt и c++

Qt Help Framework: обзор архитектуры (.qhp/.qhcp/.qch, QHelpEngine)

Введение

Сама документация Qt — справка по классам, открываемая в Qt Creator или Qt Assistant нажатием F1 — построена не на каком-то внешнем веб-движке, а на собственной технологии Qt, называемой Qt Help Framework. Эта же технология доступна разработчикам для встраивания полноценной справочной системы в собственные приложения: с поиском по контенту, индексом ключевых слов, деревом содержания и контекстной справкой по виджетам. В статье разберём общую архитектуру фреймворка и роль каждого из его файлов перед тем, как переходить к практике в следующих статьях цикла.

Концепция

Qt Help Framework строится вокруг нескольких типов файлов с чёткым разделением ответственности. .qhp (Qt Help Project) — XML-файл, описывающий структуру справки: какие HTML-страницы входят в неё, как они организованы в дерево содержания (Table of Contents), какие ключевые слова ведут к каким страницам (индекс), и где лежат сами файлы контента. Из .qhp-файла инструмент qhelpgenerator компилирует .qch (Qt Compressed Help) — единый бинарный файл, содержащий весь контент справки в сжатом и индексированном виде, готовый к распространению вместе с приложением.

.qhcp (Qt Help Collection Project) и скомпилированный из него .qhc — следующий уровень: коллекция, объединяющая несколько .qch-файлов в одну логическую базу справки (например, справка по основному приложению + справка по плагину), с общим индексом поиска по всем подключённым справочникам одновременно. В рантайме приложения весь этот скомпилированный контент читается через класс QHelpEngine, который предоставляет API для поиска, навигации по содержанию и получения данных конкретной страницы.

Пример кода: Qt Help Framework

project_root/
├── docs/
│   ├── source/                  # исходные HTML-страницы справки
│   │   ├── index.html
│   │   ├── getting_started.html
│   │   └── api_reference.html
│   ├── myapp.qhp                # описание структуры (TOC, индекс, файлы)
│   ├── myapp.qhcp                # описание коллекции (объединяет .qch)
│   └── images/
│       └── logo.png
<!-- myapp.qhp — минимальная структура проекта справки -->
<?xml version="1.0" encoding="UTF-8"?>
<QtHelpProject version="1.0">
    <namespace>com.mycompany.myapp.1.0</namespace>
    <virtualFolder>doc</virtualFolder>

    <filterSection>
        <toc>
            <section title="Начало работы" ref="source/getting_started.html">
                <section title="Установка" ref="source/getting_started.html#install" />
            </section>
            <section title="Справочник API" ref="source/api_reference.html" />
        </toc>

        <keywords>
            <keyword name="установка" ref="source/getting_started.html#install" />
            <keyword name="API" ref="source/api_reference.html" />
        </keywords>

        <files>
            <file>source/index.html</file>
            <file>source/getting_started.html</file>
            <file>source/api_reference.html</file>
            <file>images/logo.png</file>
        </files>
    </filterSection>
</QtHelpProject>
# Компиляция .qhp в готовый бинарный .qch
qhelpgenerator myapp.qhp -o myapp.qch

Пояснения к коду

Элемент <namespace> в .qhp-файле — уникальный идентификатор справочника (по аналогии с доменным именем в обратном порядке), используемый Qt Help Framework для различения разных подключённых справочников внутри одной коллекции — он должен быть глобально уникальным для конкретного продукта и обычно включает номер версии, чтобы справка для разных версий приложения не конфликтовала при одновременной установке.

Блок <toc> описывает дерево содержания, которое пользователь видит как навигационную панель слева в справочном браузере — вложенные <section> создают иерархию разделов. <keywords> формирует индекс — отдельный механизм поиска по ключевым словам, независимый от полнотекстового поиска по содержимому страниц, который Qt Help Framework строит автоматически на основе текста HTML-файлов, перечисленных в <files>.

Подводные камни

  • Несовпадение namespace между .qhp и кодом, который впоследствии регистрирует справочник в QHelpEngine. Если строка namespace в проекте справки и строка, используемая в коде приложения для обращения к конкретному справочнику, не совпадают побайтово, приложение не найдёт нужный контент при попытке его открыть, не выдавая явной ошибки о причине.
  • Забытые файлы в секции <files>. Любой файл (HTML, изображение, CSS), на который ссылаются страницы справки, но который не перечислен явно в <files>, не попадёт в скомпилированный .qch — результат: битые изображения и ссылки в уже скомпилированной и распространённой справке, обнаруживаемые только при реальном просмотре, а не на этапе компиляции.
  • Версионирование namespace без понимания последствий. Включение номера версии в namespace (com.mycompany.myapp.1.0) означает, что справка для версии 1.0 и версии 2.0 — технически разные справочники с точки зрения Qt Help Framework; при обновлении приложения нужна явная стратегия — обновлять namespace при каждом релизе (что требует логики удаления старой справки) или оставлять его неизменным между минорными версиями.
  • Путаница между ролью .qch и .qhc/.qhcp. .qch — это сама справка (контент одного продукта/модуля), а .qhc — коллекция, объединяющая несколько .qch файлов для совместного поиска; для приложения с единственным источником справки полноценная коллекция может быть избыточна, и достаточно работать с .qch напрямую через QHelpEngineCore.