简单文本查看器示例
将Qt Assistant 用作应用程序的自定义帮助查看器。

本示例演示如何在自定义应用程序中将Qt Assistant 用作定制化的帮助查看器。该过程分为两个阶段:首先,创建文档并自定义Qt Assistant ;其次,向应用程序中添加启动和控制Qt Assistant 的功能。
“简单文本查看器”应用程序允许用户选择和查看现有文件。该应用程序提供了自己的自定义文档,用户可以通过主窗口菜单栏中的“帮助”菜单,或点击应用程序“查找文件”对话框中的“帮助”按钮来访问这些文档。
该示例由四个类组成:
Assistant提供启动Qt Assistant 的功能。MainWindow是应用程序的主窗口。FindFileDialog允许用户使用通配符匹配来搜索文件。TextEdit提供了一个富文本浏览器,可确保 HTML 文档中引用的图像能够正确显示。
注意:我们将 仅针对与主要问题相关的实现部分进行说明,即让Qt Assistant 作为我们“简单文本查看器”应用程序的定制化帮助查看器。
创建文档和自定义Qt Assistant
如何以 HTML 页面的形式创建实际文档,不在本示例的讨论范围内。 通常,HTML 页面可以手动编写,也可以借助 qdoc 或 Doxygen 等文档工具生成。出于本示例的目的,我们假设 HTML 文件已经创建完毕。因此,唯一需要做的事情就是告诉Qt Assistant 如何组织和显示帮助信息。
组织文档Qt Assistant
纯 HTML 文件仅包含文本或关于特定主题的文档,但通常不包含关于多个 HTML 文档之间如何关联,以及应按何种顺序阅读的信息。 所缺失的是一个目录以及索引,以便快速访问特定的帮助内容,而无需为了查找一条信息而在大量文档中逐一浏览。
为了组织文档并使其可在Qt Assistant 上使用,我们必须创建一个 Qt Help 项目 (.qhp) 文件。项目文件中首先也是最重要的一部分是命名空间的定义。 命名空间必须是唯一的,并将作为Qt Assistant 页面 URL 的首部分。此外,我们还需设置一个虚拟文件夹,作为文档集的公共文件夹。这意味着,由两个不同命名空间标识的两个文档集可以相互引用 HTML 文件,因为这些文件都位于同一个大型虚拟文件夹中。 不过,在本示例中,我们仅有一个文档集可用,因此虚拟文件夹的名称和功能并不重要。
<?xml version="1.0" encoding="UTF-8"?>
<QtHelpProject version="1.0">
<namespace>org.qt-project.examples.simpletextviewer</namespace>
<virtualFolder>doc</virtualFolder>下一步是定义过滤器部分。过滤器部分包含目录、索引以及所有文档文件的完整列表,并可被分配任意数量的过滤器属性。 过滤器属性是一个普通字符串,可以自由选择。随后在Qt Assistant 中,用户可以定义一个引用这些属性的自定义过滤器。如果过滤器部分的属性与自定义过滤器的属性匹配,文档将被显示;否则,Qt Assistant 将隐藏该文档。
同样,由于我们只有一组文档,因此不需要Qt Assistant 的过滤功能,可以省略过滤属性。
现在,我们来构建目录。 目录中的每个条目由section 标签定义,该标签包含条目标题属性以及指向实际页面的链接。部分标签可以无限嵌套,但出于实际考虑,不建议嵌套深度超过三到四层。在本例中,我们希望为目录使用以下大纲结构:
- 简单文本查看器
- 查找文件
- 文件对话框
- 通配符匹配
- 浏览
- 打开文件
- 查找文件
在帮助项目文件中,大纲由以下内容表示:
<filterSection>
<toc>
<section title="Simple Text Viewer" ref="index.html">
<section title="Find File" ref="findfile.html">
<section title="File Dialog" ref="filedialog.html"/>
<section title="Wildcard Matching" ref="wildcardmatching.html"/>
<section title="Browse" ref="browse.html"/>
</section>
<section title="Open File" ref="openfile.html"/>
</section>
</toc>定义完目录后,我们将列出所有索引关键词:
<keywords>
<keyword name="Display" ref="index.html"/>
<keyword name="Rich text" ref="index.html"/>
<keyword name="Plain text" ref="index.html"/>
<keyword name="Find" ref="findfile.html"/>
<keyword name="File menu" ref="findfile.html"/>
<keyword name="File name" ref="filedialog.html"/>
<keyword name="File dialog" ref="filedialog.html"/>
<keyword name="File globbing" ref="wildcardmatching.html"/>
<keyword name="Wildcard matching" ref="wildcardmatching.html"/>
<keyword name="Wildcard syntax" ref="wildcardmatching.html"/>
<keyword name="Browse" ref="browse.html"/>
<keyword name="Directory" ref="browse.html"/>
<keyword name="Open" ref="openfile.html"/>
<keyword name="Select" ref="openfile.html"/>
</keywords>作为最后一步,我们需要列出构成文档的所有文件。这里需要注意的一点是,必须列出所有文件,包括图像文件,甚至包括(如果使用了)样式表。
<files>
<file>browse.html</file>
<file>filedialog.html</file>
<file>findfile.html</file>
<file>index.html</file>
<file>intro.html</file>
<file>openfile.html</file>
<file>wildcardmatching.html</file>
<file>images/browse.png</file>
<file>images/fadedfilemenu.png</file>
<file>images/filedialog.png</file>
<file>images/handbook.png</file>
<file>images/mainwindow.png</file>
<file>images/open.png</file>
<file>images/wildcard.png</file>
</files>
</filterSection>
</QtHelpProject>至此,帮助项目文件已制作完成。若要在Qt Assistant 中查看生成的文档,需将其生成Qt压缩帮助文件,并将其注册到Qt Assistant 的默认帮助集合中。
qhelpgenerator simpletextviewer.qhp -o simpletextviewer.qch
assistant -register simpletextviewer.qch若现在启动Qt Assistant ,您会看到 Qt 文档旁边显示着 Simple Text Viewer 的文档。这在测试阶段尚可接受,但对于最终版本,我们希望Qt Assistant 中仅包含 Simple Text Viewer 的文档。
自定义Qt Assistant
要让Qt Assistant 仅显示“Simple Text Viewer”文档的最简单方法,是创建我们自己的帮助集合文件。集合文件以二进制格式存储,类似于压缩的帮助文件,并由帮助集合项目文件 (*.qhcp) 生成。借助集合文件,我们可以自定义Qt Assistant 的外观,甚至某些功能。
首先,我们修改窗口标题和图标。不再显示“Qt Assistant ”,而是显示“Simple Text Viewer”,这样用户就能更清楚地知道,该帮助查看器实际上属于我们的应用程序。
<?xml version="1.0" encoding="UTF-8"?>
<QHelpCollectionProject version="1.0">
<assistant>
<title>Simple Text Viewer</title>
<applicationIcon>images/handbook.png</applicationIcon>
<cacheDirectory>QtProject/SimpleTextViewer</cacheDirectory>cacheDirectory 标签指定了用户数据目录下的一个子目录(参见Qt Help 集合文件),全文搜索的缓存文件或设置文件将存储在此处。
接下来,我们设置Qt Assistant 在新配置下首次启动时显示的页面。URL 由 Qt Help 项目文件中定义的命名空间和虚拟文件夹组成,后跟实际的页面文件名。
<startPage>qthelp://org.qt-project.examples.simpletextviewer/doc/index.html</startPage>接下来,我们将“关于”菜单项的名称更改为“关于 Simple Text Viewer”。同时,通过指定包含关于文本或图标的文件,也可修改“关于”对话框的内容。
<aboutMenuText>
<text>About Simple Text Viewer</text>
</aboutMenuText>
<aboutDialog>
<file>about.txt</file>
<icon>images/icon.png</icon>
</aboutDialog>Qt Assistant Qt Assistant 允许通过其“首选项”对话框添加或删除文档。当将 作为多个应用程序的中央帮助查看器时,此功能非常有用,但在本例中,我们实际上希望防止用户删除文档。因此,我们将“首选项”对话框中的“文档”选项卡隐藏起来。
由于在如此小的文档集中,地址栏其实并不重要,因此我们也将其关闭。通过仅保留一个过滤器区域且不设置任何过滤器属性,我们还可以禁用Qt Assistant 的过滤功能,这意味着过滤器页面和过滤器工具栏将不可用。
<enableDocumentationManager>false</enableDocumentationManager>
<enableAddressBar>false</enableAddressBar>
<enableFilterFunctionality>false</enableFilterFunctionality>
</assistant>出于测试目的,我们已经生成了压缩的帮助文件,并将其注册到Qt Assistant 的默认帮助集合中。通过以下几行代码,我们可以实现相同的效果。唯一且重要的区别在于,我们将压缩的帮助文件注册到我们自己的集合文件中,而不是默认集合中。
<docFiles>
<generate>
<file>
<input>simpletextviewer.qhp</input>
<output>simpletextviewer.qch</output>
</file>
</generate>
<register>
<file>simpletextviewer.qch</file>
</register>
</docFiles>
</QHelpCollectionProject>作为最后一步,我们需要根据帮助集合项目文件生成二进制集合文件。这可以通过运行qhelpgenerator 工具来完成。
qhelpgenerator simpletextviewer.qhcp -o simpletextviewer.qhc为了测试我们对Qt Assistant 所做的所有自定义设置,我们将集合文件名添加到命令行中:
assistant -collectionFile simpletextviewer.qhc通过 Assistant 类控制Qt Assistant
首先,我们将了解如何从远程应用程序启动并操作Qt Assistant 。为此,我们创建了一个名为Assistant 的类。
该类提供了一个用于显示文档页面的公共函数,以及一个用于确保Qt Assistant 正常运行的私有辅助函数。
在startAssistant() 函数中,通过简单地创建并启动一个 QProcess 即可启动Qt Assistant 。如果进程已经在运行,该函数将立即返回;否则,则需要配置并启动该进程。
bool Assistant::startAssistant()
{
if (!m_process) {
m_process = std::make_unique<QProcess>();
QObject::connect(m_process.get(), &QProcess::finished,
m_process.get(), [this](int exitCode, QProcess::ExitStatus status) {
finished(exitCode, status);
});
}
if (m_process->state() != QProcess::Running) {
QString app = QLibraryInfo::path(QLibraryInfo::BinariesPath);
#ifndef Q_OS_DARWIN
app += "/assistant"_L1;
#else
app += "/Assistant.app/Contents/MacOS/Assistant"_L1;
#endif
const QString collectionDirectory = documentationDirectory();
if (collectionDirectory.isEmpty()) {
showError(tr("The documentation directory cannot be found"));
return false;
}
const QStringList args{"-collectionFile"_L1,
collectionDirectory + "/simpletextviewer.qhc"_L1,
"-enableRemoteControl"_L1};
m_process->start(app, args);
if (!m_process->waitForStarted(3000)) {
showError(tr("Unable to launch Qt Assistant (%1): %2")
.arg(QDir::toNativeSeparators(app), m_process->errorString()));
return false;
}
}
return true;
}要启动该进程,我们需要Qt Assistant 的可执行文件名称,以及用于以自定义模式运行Qt Assistant 的命令行参数。可执行文件名称有些棘手,因为它取决于平台,但幸运的是,仅在 macOS 上才存在差异。
在启动Qt Assistant 时,可以通过-collectionFile 命令行参数来修改显示的文档内容。如果未带任何选项启动,Qt Assistant 将显示一组默认文档。当 Qt 已安装时,Qt Assistant 中设置的默认文档集包含 Qt 参考文档以及 Qt 随附的工具,例如Qt Designer 和qmake 。
在本例中,我们通过将应用程序专用的集合文件传递给该进程的命令行选项,用自定义文档集替换了默认文档集。
作为最后一个参数,我们添加-enableRemoteControl ,这会使Qt Assistant 监听其stdin 频道以接收命令,例如用于显示文档中特定页面的命令。然后我们启动该进程,并等待其实际运行起来。如果由于某种原因无法启动Qt Assistant ,startAssistant() 将返回 false。
现在,showDocumentation() 的实现非常简单。首先,我们确保Qt Assistant 正在运行,然后通过进程的stdin 通道发送显示page 的请求。这里非常重要的一点是,命令末尾必须以换行符结尾,以便刷新通道。
void Assistant::showDocumentation(const QString &page)
{
if (!startAssistant())
return;
QByteArray ba("SetSource ");
ba.append("qthelp://org.qt-project.examples.simpletextviewer/doc/");
m_process->write(ba + page.toLocal8Bit() + '\n');
}最后,我们需要确保在应用程序关闭时,Qt Assistant 能够被正确终止。QProcess的析构函数会直接终止进程,这意味着应用程序将无法执行保存用户设置等操作,从而导致设置文件损坏。为避免这种情况,我们在Assistant 类的析构函数中调用Qt Assistant 使其自行终止。
Assistant::~Assistant()
{
if (m_process && m_process->state() == QProcess::Running) {
QObject::disconnect(m_process.get(), &QProcess::finished, nullptr, nullptr);
m_process->terminate();
m_process->waitForFinished(3000);
}
}MainWindow 类

MainWindow 类为应用程序的主窗口提供了两个菜单:“文件”菜单允许用户打开和查看现有文件,而“帮助”菜单则提供有关应用程序和Qt的信息,并允许用户打开Qt Assistant 以显示应用程序的文档。
为了能够访问帮助功能,我们在MainWindow 的构造函数中初始化了Assistant 对象。
MainWindow::MainWindow()
: textViewer(new TextEdit)
, assistant(new Assistant)
{
...
}然后,我们为“Simple Text Viewer”应用程序创建所有操作。其中特别值得注意的是assistantAct 操作,可通过F1快捷键或“帮助”>“帮助目录”菜单项访问。该操作连接到了MainWindow 类的showDocumentation() 槽。
void MainWindow::createActions()
{
assistantAct = new QAction(tr("Help Contents"), this);
assistantAct->setShortcut(QKeySequence::HelpContents);
connect(assistantAct, &QAction::triggered, this, &MainWindow::showDocumentation);
...
}在 `showDocumentation() ` 插槽中,我们调用 `Assistant ` 类的 `showDocumentation() ` 函数,并传入文档主页的 URL。
void MainWindow::showDocumentation()
{
assistant->showDocumentation("index.html");
}最后,我们必须重写受保护的 QWidget::closeEvent() 事件处理程序,以确保在终止应用程序之前,应用程序的Qt Assistant 实例已正确关闭。
void MainWindow::closeEvent(QCloseEvent *)
{
delete assistant;
}FindFileDialog 类

“简单文本查看器”应用程序提供了一个文件查找对话框,允许用户使用通配符匹配来搜索文件。搜索在指定的目录内进行,并且用户可以选择浏览现有的文件系统以查找相关的目录。
在构造函数中,我们保存了作为参数传递的Assistant 和QTextEdit 对象的引用。Assistant 对象将用于FindFileDialog 的help() 槽中(稍后我们将看到),而QTextEdit则将用于对话框的openFile() 槽中,以显示所选文件。
FindFileDialog::FindFileDialog(TextEdit *editor, Assistant *assistant)
: QDialog(editor)
, currentEditor(editor)
, currentAssistant(assistant)
{
...
}在FindFileDialog 类中,最值得关注的是私有help() 槽。该槽与对话框的“帮助”按钮相关联,通过调用Assistant 类的showDocumentation() 函数,将当前的Qt Assistant 实例与对话框的文档一起置于前台。
void FindFileDialog::help()
{
currentAssistant->showDocumentation("filedialog.html");
}总结
为了使Qt Assistant 作为您应用程序的自定义帮助工具运行,您必须为应用程序提供一个用于控制Qt Assistant 的进程,以及一个包含 Qt Help 压缩帮助文件的自定义帮助集合文件。
有关将Qt Assistant 用作自定义帮助查看器时应用程序可用的选项和设置的更多信息,请参阅《自定义Qt Assistant 》。
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.