Введение
Помимо встраивания справки непосредственно в собственный UI приложения (предыдущая статья), .qch-файл можно открывать в Qt Assistant — отдельном, готовом приложении-справочнике, поставляемом вместе с Qt SDK. Это удобно для продуктов, где полноценная встроенная справочная система избыточна, но всё же нужен удобный, профессионально выглядящий способ просмотра документации — например, для SDK или библиотек, документация которых адресована разработчикам, уже привыкшим к Qt Assistant. В статье разберём оба способа запуска Qt Assistant из своего приложения.
Концепция
Есть два основных режима использования Qt Assistant: standalone-запуск как полностью отдельного процесса (приложение просто открывает Assistant с указанием своего .qch-файла через аргументы командной строки или файл коллекции) и встраиваемый режим через QAssistantClient-подобный механизм (управление запущенным процессом Assistant программно через его удалённый интерфейс stdin/stdout). Первый способ значительно проще в реализации и достаточен для большинства случаев, когда не требуется тонкое программное управление окном Assistant из основного приложения.
Пример кода: Интеграция с Qt
#pragma once
#include <QProcess>
#include <QStandardPaths>
#include <QDebug>
class StandaloneHelpLauncher
{
public:
explicit StandaloneHelpLauncher(const QString &collectionFilePath)
: m_collectionFilePath(collectionFilePath) {}
void showHelp(const QUrl &page = QUrl())
{
if (m_process.state() != QProcess::NotRunning) {
// Assistant уже запущен — отправляем команду навигации
// через его текстовый протокол на stdin
if (page.isValid()) {
sendCommand("setSource " + page.toString());
}
sendCommand("activateIdentifier"); // вывести окно на передний план
return;
}
const QString assistantPath = findAssistantExecutable();
if (assistantPath.isEmpty()) {
qWarning() << "Qt Assistant не найден в системе";
return;
}
QStringList arguments;
arguments << "-collectionFile" << m_collectionFilePath
<< "-enableRemoteControl"; // включаем приём команд через stdin
m_process.start(assistantPath, arguments);
if (!m_process.waitForStarted(3000)) {
qWarning() << "Не удалось запустить Qt Assistant";
return;
}
if (page.isValid()) {
sendCommand("setSource " + page.toString());
}
}
private:
void sendCommand(const QString &command)
{
m_process.write((command + "\n").toUtf8());
}
QString findAssistantExecutable()
{
// Поиск рядом с самим приложением, либо в стандартных путях
QString path = QStandardPaths::findExecutable("assistant");
if (path.isEmpty()) {
path = QStandardPaths::findExecutable("assistant",
{QCoreApplication::applicationDirPath()});
}
return path;
}
QProcess m_process;
QString m_collectionFilePath;
};
// Использование: кнопка "Справка" в главном меню приложения
#include "standalonehelplauncher.h"
void MainWindow::onHelpActionTriggered()
{
static StandaloneHelpLauncher launcher(
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/myapp_help.qhc");
launcher.showHelp(QUrl("qthelp://com.mycompany.myapp.1.0/doc/source/getting_started.html"));
}
Пояснения к коду
StandaloneHelpLauncher::showHelp() запускает процесс Qt Assistant с флагом -enableRemoteControl, который активирует простой текстовый протокол управления через стандартный ввод процесса — после запуска приложение может отправлять команды вроде setSource <url> для навигации к конкретной странице или activateIdentifier для вывода окна Assistant на передний план, не перезапуская сам процесс при каждом обращении к справке.
Проверка m_process.state() != QProcess::NotRunning предотвращает повторный запуск нового процесса Assistant при каждом нажатии кнопки «Справка», если он уже открыт — вместо этого повторное обращение просто переключает уже открытое окно на нужную страницу, что соответствует ожидаемому поведению (как, например, повторное открытие уже запущенного приложения операционной системой).
Подводные камни
- Qt Assistant должен быть либо установлен в системе, либо явно поставляться вместе с приложением. В отличие от встроенного через
QHelpEngineварианта (предыдущие статьи), который не требует ничего, кроме самого Qt SDK runtime, standalone Assistant — отдельный исполняемый файл, который нужно либо включить в дистрибутив приложения (что увеличивает размер пакета), либо рассчитывать на его наличие в системе (ненадёжное предположение для конечных пользователей, не разработчиков). - Текстовый протокол управления через stdin недокументирован столь же подробно, как основной API
QHelpEngine, и его конкретный набор команд может незначительно отличаться между версиями Qt — перед использованием в продакшене стоит протестировать совместимость с конкретной версией Assistant, поставляемой с используемой версией Qt. - Аварийное завершение процесса Assistant пользователем (закрытие через системный диспетчер задач, а не через штатное закрытие окна) оставляет
QProcessв состоянии, для которого проверкаstate()может не сразу отразить реальную недоступность процесса — следующая попытка отправить команду черезsendCommand()в этом случае не вызовет ошибки явно, но и не произведёт видимого эффекта. - Использование standalone Assistant для конечных пользователей непрограммистского продукта может создавать диссонанс в восприятии — окно справки выглядит как «ещё одно приложение Qt SDK», а не часть единого фирменного интерфейса продукта; для продуктов с акцентом на UX обычным конечным пользователям обычно предпочтительнее встроенный вариант справки (статья про
QTextBrowser/QWebEngineView), а standalone Assistant больше подходит для развивающих/SDK-инструментов, ориентированных на разработчиков.