[Qt教程] 第47篇 进阶(七) 定制Qt帮助系统
 
定制Qt帮助系统


版权声明

作者yafeilinux,转载请注明出处!


导语


       一个完善的应用程序应该提供尽可能丰富的帮助信息。在Qt中可以使用工具提示、状态提示以及“What’s This”等简单的帮助提示,也可以使用QtAssistant来提供强大的在线帮助。如果要进行详细的功能和使用的介绍,单单使用这些提示信息是不行的,这就需要提供HTML格式的帮助文本。在程序中可以通过调用Web浏览器或者使用QTextBrowser来管理和应用这些HTML文件。不过,Qt提供了更加强大的工具,那就是Qt Assistant,它支持索引和全文检索,而且可以为多个应用程序同时提供帮助,我们可以通过定制Qt Assistant来实现强大的在线帮助系统。

       为了将Qt Assistant定制为我们自己的应用程序的帮助浏览器,需要先进行一些准备工作,主要是生成一些文件,最后再在程序中启动Qt Assistant。主要的步骤如下:

1.创建HTML格式的帮助文档;
2.创建Qt帮助项目(Qt help project).qhp文件,该文件是XML格式的,用来组织文档,并且使它们可以在Qt Assistant中使用;
3.生成Qt压缩帮助(Qt compressed help).qch文件,该文件由.qhp文件生成,是二进制文件;
4.创建Qt帮助集合项目(Qt help collection project).qhcp文件,该文件是XML格式的,用来生成下面的.qhc文件;
5.生成Qt帮助集合(Qt help collection).qhc文件,该文件是二进制文件,可以使Qt Assistant只显示一个应用程序的帮助文档,也可以定制Qt Assistant的外观和一些功能;
6.在程序中启动Qt Assistant。


环境:Windows Xp + Qt 4.8.5+QtCreator2.8.0



目录


一、创建HTML 格式的帮助文档
二、创建.qhp 文件
三、生成.qch 文件
四、创建.qhcp 文件
五、生成.qhc 文件
六、在程序中启动QtAssistant




正文



一、创建HTML格式的帮助文档


1. 新建Qt Gui 应用,项目名称为“myWhatsThis ”,类名为“MainWindow ”,基类保持QMainWindow 不变。


2. 然后可以通过各种编辑器例如Microsoft Word 来编辑要使用的文档,最后保存为HTML 格式的文件,例如这里我们创建了5 个HTML 文件。然后在项目目录中新建文件夹,命名为“documentation ”,再将这些HTML 文件放入其中。再在documentation 文件夹中再新建一个“images ”文件夹,往里面复制一个图标图片,以后将作为Qt Assistant 的图标,例如这里使用了yafeilinux.png 图片。


二、创建.qhp文件

首先在documentation文件夹中创建一个文本文件,然后进行编辑,最后另存为“myHelp.qhp”,注意后缀为.qhp。文件的内容如下:


<?xml version="1.0"encoding="GB2312"?>
<QtHelpProjectversion="1.0">
<namespace>yafeilinux.myHelp</namespace>
<virtualFolder>doc</virtualFolder>
<filterSection>
   <toc>
     <section title=" 我的帮助"ref="./index.html">
       <section title=" 关于我们"ref="./aboutUs.html">
         <section title=" 关于yafeilinux"ref="./about_yafeilinux.html"></section>
         <section title=" 关于Qt Creator 系列教程" ref="./about_QtCreator.html"></section>
       </section>
       <section title=" 加入我们"ref="./joinUs.html"></section>
     </section>
   </toc>
   <keywords>
     <keyword name=" 关于"ref="./aboutUs.html"/>
     <keyword name="yafeilinux" ref="./about_yafeilinux.html"/>
     <keyword name="Qt Creator"ref="./about_QtCreator.html"/>
   </keywords>
   <files>
     <file>about_QtCreator.html</file>
     <file>aboutUs.html</file>
     <file>about_yafeilinux.html</file>
     <file>index.html</file>
     <file>joinUs.html</file>
     <file>images/*.png</file>
   </files>
</filterSection>
</QtHelpProject>


        这个.qhp 文件是XML 格式的,对于XML 格式不是这里介绍的重点,我们主要讲解其中的内容,如果大家想了解XML 格式相关的知识,可以参考 这里。在第一行是XML 序言,这里指定了编码encoding 为GB2312 ,这样就可以使用中文了,如果只想使用英文,那么编码一般是UTF-8 ;第二行指定了QtHelpProject 版本为1.0 ;第三行指定了命名空间namespace ,每一个.qhp 文件的命名空间都必须是唯一的,命名空间会成为Qt Assistant 中的页面的URL 的第一部分,这个在后面的内容中会涉及到;第四行指定了一个虚拟文件夹virtualFolder ,这个文件夹并不需要创建,它只是用来区分文件的;再下面的过滤器部分filterSection 标签包含了目录表、索引和所有文档文件的列表。过滤器部分可以设置过滤器属性,这样以后可以在Qt Assistant 中通过过滤器来设置文档的显示有否,不过,因为我们这里只有一个文档,所以不需要Qt Assistant 的过滤器功能,这里也就不需要设置过滤器属性;在目录表toc (table ofcontents )标签中创建了所有HTML 文件的目录,指定了它们的标题和对应的路径,这里设定的目录表为:

♦  我的帮助
    ♦  关于我们
            ♦ 关于yafeilinux
            ♦ 关于Qt Creator系列教程
    ♦ 加入我们


然后是keywords标签,它指定了所有索引的关键字和对应的文件,这些关键字会显示在Qt Assistant的索引页面;在files标签中列出了所有的文件,也包含图片文件。



三、生成.qch文件


       这里为了测试创建的文件是否可用,可以先生成.qch文件,然后在QtAssistant中注册它。这样运行QtAssistant就会看到我们添加的文档了。不过,这一步不是必须的。我们打开命令行控制台,然后使用cd命令跳转到项目目录的documentation目录中,分别输入下面的命令后按下回车:


qhelpgeneratormyHelp.qhp –o myHelp.qch
assistant –registermyHelp.qch
 


        要保证命令可以正常运行,前提是已经将Qt 安装目录的bin 目录的路径添加到了系统的PATH 环境变量中。命令运行结果如下图所示。


 


当注册成功时,会显示“Documentationsuccessfully registered ”提示对话框。这时在开始菜单中启动Qt Assistant (或者直接在命令行输入assistant 来启动Qt Assistant ),可以发现已经出现了我们的HTML 文档,如下图所示。



 



四、创建.qhcp文件



要想使Qt Assistant只显示我们自己的帮助文档的最简单的方法就是生成帮助集合文件即.qhc文件,要生成.qhc文件,首先要创建.qhcp文件。在documentation文件夹中新建文本文档,对其进行编辑,最后另存为“myHelp.qhcp”,注意后缀为.qhcp。这里还要创建一个名为“about.txt”的文本文件,在其中输入一些该帮助的说明信息,作为QtAssistant的About菜单的显示内容。myHelp.qhcp文件的内容如下:



<?xml version="1.0"encoding="GB2312"?>
<QHelpCollectionProjectversion="1.0">
<assistant>
<title> 我的帮助系统</title>
<applicationIcon>images/yafeilinux.png</applicationIcon>
<cacheDirectory>cache/myHelp</cacheDirectory>
<homePage>qthelp://yafeilinux.myHelp/doc/index.html</homePage>
<startPage>qthelp://yafeilinux.myHelp/doc/index.html</startPage>
<aboutMenuText>
   <text> 关于该帮助</text>
</aboutMenuText>
<aboutDialog>
   <file>./about.txt</file>
   <icon>images/yafeilinux.png</icon>
</aboutDialog>
<enableDocumentationManager>false</enableDocumentationManager>
<enableAddressBar>false</enableAddressBar>
<enableFilterFunctionality>false</enableFilterFunctionality>
</assistant>
<docFiles>
<generate>
   <file>
     <input>myHelp.qhp</input>
     <output>myHelp.qch</output>
   </file>
</generate>
<register>
   <file>myHelp.qch</file>
</register>
</docFiles>
</QHelpCollectionProject>



        在assistant 标签中是对Qt Assistant 的外观和功能的定制,其中设置了标题、图标、缓存目录、主页、起始页、About 菜单文本、关于对话框的内容和图标等,还关闭了一些没有用的功能。对于缓存目录cacheDirectory ,是进行全文检索等操作时缓存文件要存放的位置。对于主页homePage 和起始页startPage ,这里使用了第二步中提到的Qt Assistant 的页面的URL ,这个URL 由“qthelp:// ”开始,然后是在.qhp 文件中设置的命名空间,然后是虚拟文件夹,最后是具体的HTML 文件名。因为Qt Assistant 可以添加或者删除文档来为多个应用程序提供帮助,但是这里只是为一个应用程序提供帮助,并且不希望删除我们的文档,所以禁用了文档管理器documentation manager ;因为这里的文档集很小,而且只有一个过滤器部分,所以也关闭了地址栏address bar 和过滤器功能filter functionality 。
        在前面第三步中我们已经生成了.qch 文件并且在Qt Assistant 中进行了注册,但那只是为了测试文件是否可用,其实完全可以跳过第三步,因为在这里的docFiles 标签中就完成了第三步的操作。不过与第三步不同的是,第三步是在默认的集合文件中注册的,而这里是在我们自己的集合文件中注册的。



五、生成.qhc文件

在命令行输入如下命令:



qcollectiongenerator myHelp.qhcp –omyHelp.qhc



        输出结果如下图所示。


 



为了测试我们定制的QtAssistant ,可以在输入如下命令:


assistant –collectionFile myHelp.qhc



这里在运行Qt Assistant时指定了集合文件为我们自己的.qhc文件,所以运行后只会显示我们自己的HTML文档。可以看到,现在QtAssistant的图标也更改了,打开“Help”菜单中的“关于该帮助”菜单,这里是前面添加的about.txt文件的内容,效果如下图所示。


 



六、在程序中启动Qt Assistant

这里先要将Qt安装目录的bin目录中的assistant.exe程序复制到我们项目目录的documentation目录中。为了启动Qt Assistant,先要创建了一个Assistant类。首先向项目中添加新文件,模板选择C++ Class,类名为“Assistant”,基类不填写,类型信息选择无。然后将assistant.h文件更改如下:



#ifndef ASSISTANT_H
#define ASSISTANT_H
#include <QtCore/QString>
class QProcess;


class Assistant
{
public:
    Assistant();
    ~Assistant();
    void showDocumentation(const QString &file);
private:
    bool startAssistant();
    QProcess *proc;
};
#endif // ASSISTANT_H



        在Assistant 类中主要是使用QProcess 类创建一个进程来启动Qt Assistant 。下面是assistant.cpp 文件的内容:



#include <QtCore/QByteArray>
#include <QtCore/QProcess>
#include <QtGui/QMessageBox>
#include "assistant.h"


Assistant::Assistant()
   : proc(0)
{
}


Assistant::~Assistant()
{
   if (proc && proc->state() == QProcess::Running) {
       // 试图终止进程
       proc->terminate();
       proc->waitForFinished(3000);
   }
   // 销毁proc
   delete proc;
}


// 显示文档
void Assistant::showDocumentation(const QString &page)
{
   if (!startAssistant())
       return;
   QByteArray ba("SetSource ");
   ba.append("qthelp://yafeilinux.myHelp/doc/");
   proc->write(ba + page.toLocal8Bit() + '\n');
}


// 启动Qt Assistant
bool Assistant::startAssistant()
{
   // 如果没有创建进程,则新创建一个
   if (!proc)
       proc = new QProcess();


   // 如果进程没有运行,则运行assistant,并添加参数
   if (proc->state() != QProcess::Running) {
     QString app = QLatin1String("../myWhatsThis/documentation/assistant.exe");
       QStringList args;
       args << QLatin1String("-collectionFile")
            << QLatin1String("../myWhatsThis/documentation/myHelp.qhc");
       proc->start(app, args);
       if (!proc->waitForStarted()) {
            QMessageBox::critical(0, QObject::tr("my help"),
                QObject::tr("Unable to launch Qt Assistant (%1)").arg(app));
            return false;
       }
   }
   return true;
}



        在startAssistant() 函数中使用QProcess 创建了一个进程来启动Qt Assistant ,这里使用了命令行参数来使用帮助集合文件,对于assistant.exe 和myHelp.qhc 都使用了相对地址;在showDocumentation() 函数中可以指定具体的页面作为参数来使Qt Assistant 显示指定的页面;在析构函数中,如果进程还在运行,则终止进程,最后销毁了进程指针。
        下面来使用Assistant 类来启动Qt Assistant 。在mainwindow.h 文件中先添加前置声明:


class Assistant;


        再添加private 对象指针声明:


Assistant *assistant;


        然后添加一个私有槽:


private slots:
    void startAssistant();


        现在到mainwindow.cpp 文件中进行更改。添加头文件包含#include "assistant.h",然后在构造函数中添加如下代码:


QAction *help = new QAction("help",this);
ui->mainToolBar->addAction(help);
connect(help, SIGNAL(triggered()), this, SLOT(startAssistant()));
 
// 创建Assistant对象
assistant = new Assistant;


        这里创建了一个“help ”动作,并将它添加到了工具栏中,可以使用该动作启动QtAssistant 。下面是startAssistant() 槽的定义:


void MainWindow::startAssistant()
{
   // 按下“help”按钮,运行Qt Assistant,显示index.html页面
   assistant->showDocumentation("index.html");
}


        最后在析构函数中销毁assistant 指针,即在MainWindow::~MainWindow()函数中添加如下代码:


// 销毁assistant
delete assistant;


        现在运行程序,按下工具栏上的“help ”动作,就可以启动Qt Assistant 了。这里还要提示一下,如果要发布该程序,那么需要将documentation 目录复制到发布目录中,这时运行程序。



结语



使用Qt定制帮助系统,可以制作功能强大的上下文相关的帮助文档,而对于一个优秀的软件而言,帮助菜单是必须有的。