Огромный объём документации по функционалу библиотек Qt уже включён в состав дистрибутива Qt Creator. Таким образом, при работе над кодом не нужно переключаться между IDE и веб-браузером чтобы найти интересующую информацию. Очень удобно!

Но как быть, если хочется иметь свою справку на свой продукт, и чтобы её было также удобно использовать при работе в Qt Creator, наряду со стандартной справкой Qt? Чтобы можно было переходить из редактора кода непосредственно на страницы интересующих нас функций/типов/классов или же каких-то статей?

В этой статье мы поделимся опытом, полученным при интеграции в Qt Creator документации на ОС "Нейтрино" и картографический пакет "ПК ЦКИ", а также продемонстрируем на простом примере алгоритм формирования документации для Qt Creator, состоящий из следующих шагов:

1) Подготовка собственной справки в виде страниц формата HTML

2) Формирование файла структуры и генерация документации

3) Интеграция получившейся документации

Итак, приступим!

Подготовка

В Qt в качестве формата справочных материалов используется формат HTML. Как подготовить HTML страницы решать вам: можно сверстать её вручную, можно воспользоваться сторонними генераторами документации, например, Doxygen. Мы в нашей компании используем собственную систему генерации документации, почитать о которой можно в этой статье.

Для простоты создадим HTML страницу вручную и поместим ее в отдельную директорию. Пусть наша рабочая директория для генерации справки будет ~/qch_test, и нашу страничку мы поместим туда и назовём basic.html. У страницы будет вот такая разметка:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Hello, world!</title>
<link rel="stylesheet" type="text/css" href="./basic.css" />
</head>
<body bgcolor="#ffffff">

Hello, world!

<h2 class="syntax">Style!</h2>

</body>
</html>

Видим, что в тексте упомнается стиль basic.css. В нём будут содержаться свойства для стилизации класса syntax тега h2. Файл стиля basic.css будет располагаться также в директории ~/qch_test.

body {
	margin-left: 10px;
}

h2.syntax {
	background: #f0f0f0;
	font-family: courier, monospace;
	color: brown;
	margin-left: 0px;
	margin-right: 10px;
	padding-left: 3%;
	padding-right: 3%;
	padding-top: 3%;
	padding-bottom: 3%;
}

Формирование структуры справки

Теперь, когда у нас имеются готовые файлы, надо их как-то друг с другом связать. Ведь для справки может понадобиться не только лишь CSS, а, например, еще и изображения, медиафайлы. А в случае, если у нас будет полноценная справка на проект, то необходимо еще и выстроить иерархию страниц (Table of Contents)!

Вышеописанные задачи решает .qhp (Qt Help Project) файл. Для нашего простого примера содержимое файла будет таким (файл расположим в ~/qch_test/basic.qhp):

<?xml version="1.0" encoding="UTF-8"?>

<QtHelpProject version="1.0">
   <namespace>ru.kpda.doc.basic</namespace>
   <virtualFolder>html</virtualFolder>
   <filterSection>

      <toc>
         <section title="Привет, мир!" ref="basic.html"/>
      </toc>

      <keywords>
         <keyword name="Hello" ref="basic.html"/>
      </keywords>

      <files>
         <file>basic.html</file>
         <file>basic.css</file>
      </files>

   </filterSection>
</QtHelpProject>

Более подробно о создании .qhp файла можно почитать в официальной справке Qt. А пока рассмотрим наш пример, что же у нас тут содержится? Далее по тексту .qch файл будем именовать томом справки.

basic.qhp

Описание

Комментарий

<namespace>

Пространство имён для тома справки. По факту используется лишь как отображаемое имя в настройках при добавлении/удалении тома.

У томов справки Qt пространство имён имеет следующий вид:

org.qt-project.qtsvg.5153

<virtualFolder>

Добавление исходных страниц в дополнительную папку, влияет на адрес страницы внутри системы справки.

qthelp://ru.kpda.doc.basic/html/basic.html

<toc>

Блок построения иерархии страниц справки внутри тома. В этом блоке перечисляются все страницы, которые должны войти в том документации.

Дочерние страницы по отношению к текущей должны располагаться внутри её тега <section>...</section>. Если страница не имеет дочерних страниц, можно не указывать </section>, ограничившись />.

<keywords>

Блок связывания ключевых слов с конкретными страницами тома справки. Эти ключевые слова анализируются при поиске по справке, а также позволяют прямо из редактора кода перейти к странице справки на функцию/тип/класс по нажатию клавиши F1.

Допускается использование одного ключевого слова для нескольких страниц.

<files>

Блок указания ВСЕХ используемых файлов, необходимых для тома справки. Это обязательно все HTML-страницы, опционально можно указать файлы стилей, изображений, и прочих материалов.

Если в HTML странице присутствует, например, ссылка на изображение, а в .qhp файле изображение не включено в блок <files>, то никакой ошибки и/или предупреждения не возникнет - просто у вас не будет на странице картинки.

Мы в двух шагах от заветной цели. Теперь необходимо сгенерировать файл формата .qch (Qt Compressed Help) - это файл, "под капотом" представляющий собой базу данных SQLite, внутри которой будут находиться все файлы, описанные в .qhp файле, включая его самого. Получить этот .qch файл мы можем при помощи вызова утилиты qhelpgenerator.

Установка утилиты максимально проста, например, для Ubuntu:

sudo apt-get install qhelpgenerator-qt5

После установки выполняем следующую команду из директории ~/qch_test:

qhelpgenerator basic.qhp -o basic.qch
Что мы получаем в результате всех выполненных действий
Что мы получаем в результате всех выполненных действий

Интеграция

Осталось только подключить наш .qch файл и посмотреть на получившийся результат.

Перед этим стоит отметить, что "дебажить" получившийся .qch файл лучше в приложении Qt Assistant, так как в нём справка отображается так, как вы ожидаете, например, также как в любом веб-браузере. В Qt Creator могут возникнуть неожиданности, о которых чуть позже.

Qt Assistant

Открываем Qt Assistant, заходим в меню Edit > Preferences > Documentation > Add. Выбираем сгенерированный .qch файл, сохраняем изменения при помощи Apply и OK.

Добавление тома справки в Qt Assistant
Добавление тома справки в Qt Assistant

Для просмотра получившейся документации обращаемся к меню слева, выбираем там нужный раздел документации.

Демонстрация отображения тестовой страницы в Qt Assistant
Демонстрация отображения тестовой страницы в Qt Assistant

Qt Creator

Открываем Qt Creator, заходим в меню Tools > Options > Help > Documentation > Add. Выбираем сгенерированный .qch файл, сохраняем изменения при помощи Apply и OK.

Добавление тома справки в Qt Creator
Добавление тома справки в Qt Creator

Для просмотра получившейся документации нужно зайти в Help > Contents и выбрать нужный раздел документации.

Также можно подложить .qch файл в директорию /usr/share/qt5/doc. Тогда приложения подхватят его автоматически после перезапуска!

Если команда разработчиков использует Qt Creator из состава некого контейнера, то рекомендуется выстроить процесс по автоматическому обновлению справки и интеграции этой справки в состав Qt Creator, который уже в свою очередь будет интегрироваться в контейнер. Для этого отлично подходят системы CI/CD.

Индексация

Ранее в статье рассматривалось создание .qhp файла, в котором мы указывали ключевые слова при помощи ключевого слова <keyword>. Эти ключевые слова можно просмотреть в разделе Help > Index. В нашем примере там будет лишь одно ключевое слово "Hello", а вот для "боевой" документации список ключевых слов может быть огромным, а также одинаковые ключевые слова могут встречаться на разных страницах. Ниже на скриншоте как раз такой пример (ключевое слово /etc/hosts используется много где):

Ключевое слово /etc/hosts встречается в справке на нескольких страницах
Ключевое слово /etc/hosts встречается в справке на нескольких страницах

Пожалуй, самое полезное применение механизма индексирования это открытие страницы справки путём наведения курсора на имя функции/класса/типа и нажатия клавиши F1.

На скриншоте ниже представлен исходный код демонстрационного приложения, входящего в состав ПК ЦКИ для ОС «Нейтрино». Всем нашим закзачикам передаётся исходный код этого демонстрационного приложения, чтобы им было легче разобраться в предоставляемом API. Интеграция справки в Qt Creator позволяет упростить и ускорить процесс ознакомления с публичными интерфейсами как для заказчиков, так и для новых разработчиков.

Просмотр справки по функции непосредственно в редакторе по нажатию клавиши F1
Просмотр справки по функции непосредственно в редакторе по нажатию клавиши F1

Для системного программирования под ОС «Нейтрино» справка позволяет быстро уточнить детали реализации той или иной функции или утилиты в ОС «Нейтрино».

Просмотр справки по функции strtoul() непосредственно в редакторе по нажатию клавиши F1
Просмотр справки по функции strtoul() непосредственно в редакторе по нажатию клавиши F1

Нюансы

Хоть и файл формата .qch является универсальным для всех приложений Qt, мы обнаружили, что отображение сгенерированных нами .qch файлов отличается в Qt Creator и в Qt Assistant. Документация отображается «1 в 1» также корректно, как в любом веб-браузере, только в Qt Assistant. В Qt Creator же вылезают проблемы, например, мы столкнулись с "разъезжающимися" ячейками таблиц, лишними границами у ячеек и некорректным выравниванием текста в заголовках таблиц:

Несоответствие внешнего вида справки в Qt Assistant (слева) и в Qt Creator (справа)
Несоответствие внешнего вида справки в Qt Assistant (слева) и в Qt Creator (справа)

С чем же связаны отличия в отображаемой справке, если .qch-файл один и тот же? Тем более, если в .qch лежат наши .css файлы стилей, которые, очевидно, применились, но как будто бы неполностью.

Тут стоит обратиться к репозиторию Qt Creator и пролистать README, увидеть, что для отображения справочных страниц в нём используется некий движок, а затем перейти в репозиторий этого движка - litehtml. Далее, в README репозитория данного движка можно найти неприметную ссылку на таблицу поддерживаемых селекторов и свойств CSS.

Многие селекторы и свойства CSS не поддерживаются движком litehtml
Многие селекторы и свойства CSS не поддерживаются движком litehtml

Оказывается, собака была зарыта именно тут. В нашем случае наблюдалось странное поведение у таблиц: каждая ячейка получила внешний отступ от всех соседних. Мы проанализировали наши CSS-файлы и сравнили используемые в них свойства CSS с вышеупомянутой таблицей.

И действительно, у нас имелось неподдерживаемое (на момент написания статьи) свойство table-layout. После его удаления ситуация лучше не стала. Далее подозрение пало на самого явного кандидата: свойство border-collapse, который заявлено как поддерживаемое, однако, разъезд ячеек друг от друга не починило и оно.

Решение в итоге оказалось следующим: необходимо было явно прописать внешний отступ (margin) у ячеек таблицы и установить его в 0.

Помимо этого, чтобы отключить у ячейки отображение боковых границ, недостаточно указать border-left: 0px;: нужно указывать border-left: transparent;.

Таким образом, после этих небольших фиксов документация в Qt Creator стала отображаться также, как в Qt Assistant и в веб-браузерах.


На этом всё! Надеюсь, тому, кто будет решать аналогичный квест с генерацией справки для Qt Creator, эта статья окажется полезной!

Комментарии (0)