Огромный объём документации по функционалу библиотек 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> |
Блок построения иерархии страниц справки внутри тома. В этом блоке перечисляются все страницы, которые должны войти в том документации. |
Дочерние страницы по отношению к текущей должны располагаться внутри её тега |
<keywords> |
Блок связывания ключевых слов с конкретными страницами тома справки. Эти ключевые слова анализируются при поиске по справке, а также позволяют прямо из редактора кода перейти к странице справки на функцию/тип/класс по нажатию клавиши F1. |
Допускается использование одного ключевого слова для нескольких страниц. |
<files> |
Блок указания ВСЕХ используемых файлов, необходимых для тома справки. Это обязательно все HTML-страницы, опционально можно указать файлы стилей, изображений, и прочих материалов. |
Если в HTML странице присутствует, например, ссылка на изображение, а в .qhp файле изображение не включено в блок |
Мы в двух шагах от заветной цели. Теперь необходимо сгенерировать файл формата .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 Creator
Открываем Qt Creator, заходим в меню Tools > Options > Help > Documentation > Add. Выбираем сгенерированный .qch файл, сохраняем изменения при помощи Apply и OK.
Для просмотра получившейся документации нужно зайти в Help > Contents и выбрать нужный раздел документации.
Также можно подложить .qch файл в директорию
/usr/share/qt5/doc
. Тогда приложения подхватят его автоматически после перезапуска!
Если команда разработчиков использует Qt Creator из состава некого контейнера, то рекомендуется выстроить процесс по автоматическому обновлению справки и интеграции этой справки в состав Qt Creator, который уже в свою очередь будет интегрироваться в контейнер. Для этого отлично подходят системы CI/CD.
Индексация
Ранее в статье рассматривалось создание .qhp файла, в котором мы указывали ключевые слова при помощи ключевого слова <keyword>
. Эти ключевые слова можно просмотреть в разделе Help > Index. В нашем примере там будет лишь одно ключевое слово "Hello", а вот для "боевой" документации список ключевых слов может быть огромным, а также одинаковые ключевые слова могут встречаться на разных страницах. Ниже на скриншоте как раз такой пример (ключевое слово /etc/hosts
используется много где):
Пожалуй, самое полезное применение механизма индексирования это открытие страницы справки путём наведения курсора на имя функции/класса/типа и нажатия клавиши F1.
На скриншоте ниже представлен исходный код демонстрационного приложения, входящего в состав ПК ЦКИ для ОС «Нейтрино». Всем нашим закзачикам передаётся исходный код этого демонстрационного приложения, чтобы им было легче разобраться в предоставляемом API. Интеграция справки в Qt Creator позволяет упростить и ускорить процесс ознакомления с публичными интерфейсами как для заказчиков, так и для новых разработчиков.
Для системного программирования под ОС «Нейтрино» справка позволяет быстро уточнить детали реализации той или иной функции или утилиты в ОС «Нейтрино».
Нюансы
Хоть и файл формата .qch является универсальным для всех приложений Qt, мы обнаружили, что отображение сгенерированных нами .qch файлов отличается в Qt Creator и в Qt Assistant. Документация отображается «1 в 1» также корректно, как в любом веб-браузере, только в Qt Assistant. В Qt Creator же вылезают проблемы, например, мы столкнулись с "разъезжающимися" ячейками таблиц, лишними границами у ячеек и некорректным выравниванием текста в заголовках таблиц:
С чем же связаны отличия в отображаемой справке, если .qch-файл один и тот же? Тем более, если в .qch лежат наши .css файлы стилей, которые, очевидно, применились, но как будто бы неполностью.
Тут стоит обратиться к репозиторию Qt Creator и пролистать README, увидеть, что для отображения справочных страниц в нём используется некий движок, а затем перейти в репозиторий этого движка - litehtml. Далее, в README репозитория данного движка можно найти неприметную ссылку на таблицу поддерживаемых селекторов и свойств CSS.
Оказывается, собака была зарыта именно тут. В нашем случае наблюдалось странное поведение у таблиц: каждая ячейка получила внешний отступ от всех соседних. Мы проанализировали наши CSS-файлы и сравнили используемые в них свойства CSS с вышеупомянутой таблицей.
И действительно, у нас имелось неподдерживаемое (на момент написания статьи) свойство table-layout. После его удаления ситуация лучше не стала. Далее подозрение пало на самого явного кандидата: свойство border-collapse, который заявлено как поддерживаемое, однако, разъезд ячеек друг от друга не починило и оно.
Решение в итоге оказалось следующим: необходимо было явно прописать внешний отступ (margin
) у ячеек таблицы и установить его в 0.
Помимо этого, чтобы отключить у ячейки отображение боковых границ, недостаточно указать border-left: 0px;
: нужно указывать border-left: transparent;
.
Таким образом, после этих небольших фиксов документация в Qt Creator стала отображаться также, как в Qt Assistant и в веб-браузерах.
На этом всё! Надеюсь, тому, кто будет решать аналогичный квест с генерацией справки для Qt Creator, эта статья окажется полезной!