Qt—帮助系统

x33g5p2x  于2022-04-14 转载在 其他  
字(9.0k)|赞(0)|评价(0)|浏览(379)

一个完善的应用程序应该提供尽可能丰富的帮助信息。Qt中可以使用工具提示、状态提示以及“What’s This”等简单的帮助提示,也可以使用Qt Assistant来提供强大的在线帮助。

简单的帮助提示

已经讲到了工具提示和状态提示,这里简单介绍“What’s This”帮助提示运行一个对话框窗口时会看到,在标题栏中有一个“?”图标,按下它就会进入“WhatThis”模式,这时如果哪个部件设置了“What’s This”帮助提示,那么当鼠标移动到它面时就会弹出一个悬浮的文本框显示相应的帮助提示。下面来看一个具体例子。

新建Qt Widgets应用项目名称为mywhatsthis,类名为MainWindow ,基类保持QMainWindow不变。建完项目后,单击 mainwindow.ui文件进入设计模式。

在界面上单击,在弹出的级联多单中选择“改变‘这是什么’"项,则弹出“编辑这是什么”对话框,可以在这里输入文本者添加图片来设置“What’s This”帮助提示。

这里输入“这是主窗口”,然后将文本改红色,最后单击“确定”按钮关闭该对话框。现在运行程序,按下Shift+F1键就可以显示提示信息了。

点击主界面会显示这是主窗口

有时也想添加一个“?”图标进入“What’s This”模式,这可以通过在代码中使用QWhatsThis类来实现。现在进入mainwindow.cpp文件中,先添加头文件#incluc< QWhatsThis>,然后在构造函数中添加如下代码:

QAction *action = QWhatsThis::createAction(this);
    ui->mainToolBar->addAction(action);

这里使用了QWhatsThis类的 createAction()函数创建了一个“What’s This”图标,然后将它添加到了工具栏中。

运行程序,按下“What’s This”图标,并在主界面上单击就可以显示提示信息了。

另外,QWhatsThis类还提供了enter WhatsThisMode()来进入“What’s This”模式。要为一个部件提供“What’s This”提示,也可以在代码中通过调用该部件的set WhatsThis()函数来实现。
要进行详细的功能和使用的介绍,则需要提供HTML格式的帮助文本。在程序中可以通过调用Web浏览器或者使用QTextBrowser来管理和应用这些HTML文件。不过,Qt提供了更加强大的工具,那就是Qt Assistant,它支持索引和全文检索,而且可以为多个应用程序同时提供帮助,可以通过定制Qt Assistant来实现强大的在线帮助系统。

定制 Qt Assistant

需要先做些准备:
①创建HTML格式的帮助文档;
②创建Qt帮助项目(Qt help project).qhp文件,该文件是XML格式的,用来组织文档,并且使它们可以在Qt Assistant中使用;
③生成Qt压缩帮助(Qt compressed help).qch文件,该文件由.qhp文件生成,是二进制文件;
④创建Qt帮助集合项目(Qt help collection project).qhcp文件,该文件是XML格式的,用来生成下面的.qhc文件;
⑤生成Qt帮助集合(Qt help collection). qhc文件,该文件是二进制文件,可以使Qt Assistant只显示一个应用程序的帮助文档,也可以定制Qt Assistant的外观和一此功能;
⑥在程序中启动Qt Assistant。

下面通过一个具体例子来讲解整个过程。这里还在前一节程序的基础上进行更改。
第一步,创建HTML格式的帮助文档。可以通过各种编辑器(如MicrosoftWord)来编辑要使用的文档,最后保存为HTML格式的文件。

例如,这里创建了5个HTML文件。然后在项目目录中新建文件夹,命名为documentation,再将这些HTML文件放入其中。

在documentation文件夹中再新建一个images文件夹,往里面复制一个图标图片,以后将作为Qt Assistant的图标,例如,这里使用了yafeilinux.png图片。

第二步,创建.qhp文件。首先在 documentation文件夹中创建一个文本文件,然后进行编辑,最后另存为
myHelp.qhp(使用UTF-8编码),注意后缀为.qhp。

文件的内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<QtHelpProject version="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格式的。

  1. 第一行是XML序言,这里指定了编码encoding为UTF-8;
  2. 第二行指定了QtHelpProject版本为1.0;
  3. 第三行指定了命名空间namespace,每一个.qhp文件的命名空间都必须是唯一的,命名空间会成为Qt Assistant页面 URL的第一部分,这个在后面的内容中会涉及;
  4. 第四行指定了一个虚拟文件夹 virtualFolder,这个文件夹并不需要创建,它只是用来区分文件的;再下面的过滤器部分filterSection标签包含了目录表、索引和所有文档文件的列表。过滤器部分可以设置过滤器属性,这样以后可以在Qt Assistant中通过过滤器来设置文档的显示有否;不过,因为这里只有一个文档,所以不需要Qt Assistant的过滤器功能,这里也就不需要设置过滤器属性。

目录表toc(table of contents)标签中创建了所有HTML文件的目录,指定了它们的标题和对应的路径,这里设定的目录表为:

然后是 keywords标签,它指定了所有索引的关键字和对应的文件,这些关键字会显示在Qt Assistant的索引页面;

在files标签中列出了所有的文件,也包含图片文件。

第三步,生成.qch文件。这里为了测试创建的文件是否可用,可以先生成.qch文件,然后在Qt Assistant中注册它。

这样运行Qt Assistant就会看到添加的文档了。不过,这一步不是必须的。

从开始菜单打开Qt自带的命令行提示符工具(Qt 5.6 forDesktop),然后使用cd命令跳转到项目目录的documentation目录中,分别输入下面的命令后按下回车:

qhelpgenerator myHelp.qhp - o myHelp.qch
assistant -register myHelp.qch

命令行运行结果如图

命令运行结果如图9-2所示。注册成功,则显示 Documentation successfully reg-istered提示对话框。

这时在开始菜单中启动Qt Assistant(或者直接在命令行输入 assistant来启动Qt Assistant)可以发现,已经出现了我们的 HTML文档,如图9-3所示。

第四步,创建.qhcp 文件。要想使Qt Assistant 只显示我们自己的帮助文档的最简单方法就是生成帮助集合文件,即.qhc 文件,那么首先要创建.qhcp文件。在
documentation文件夹中新建文本文档,并对其进行编辑,最后另存为myHelp.qhcp(使用UTF-8编码),注意后缀为.qhcp。

这里还要创建一个名为about. txt的文本文件,在其中输入一些该帮助的说明信息,作为Qt Assistant 的 About菜单的显示内容。myHelp.qhcp文件的内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<QHelpCollectionProject version="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-o myHelp.qhc

为了测试定制的Qt Assistant ,输入如下命令:

assistant -collectionFile myHelp.qhc

这里在运行Qt Assistant时指定了集合文件为自己的.qhc文件,所以运行后只会显示自己的HTML文档。可以看到,现在Qt Assistant的图标也更改了,选择“帮助→关于该帮助”菜单项,这里是前面添加的about.txt文件的内容。

第六步,在程序中启动Qt Assistant。这里先要将Qt安装目录的bin目录中的assistant. exe程序复制到项目目录的documentation目录中。然后在上一节的程序中进行更改。为了启动Qt Assistant,须先创建了一个Assistant类。

首先向项目中添加新文件,模板选择C++类,类名为Assistant,基类不填写。完成后将assistant.h文件更改如下:

#ifndef ASSISTANT_H
#define ASSISTANT_H
#include <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,进程的知识会在第19章讲解。更改assistant.cpp文件的内容如下:

#include <QByteArray>
#include <QProcess>
#include <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, &QAction::triggered, this, &MainWindow::startAssistant);

    // 创建Assistant对象
    assistant = new Assistant;

这里创建了一个help动作,并将他添加到工具栏中,可以使用该动作启动Qt Assistant。

下面添加statrAssistant()槽的定义:

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

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

MainWindow::~MainWindow()
{
    delete ui;
    // 销毁assistant
    delete assistant;
}

现在运行程序,按下工具栏上的 help动作就可以启动Qt Assistant了。

这里还要提示一下,如果要发布该程序,那么需要将documentation目录复制到发布目录中,这时运行程序,还会提示缺少一些dll文件,那么就可以根据提示在Qt安装目录的 bin目录中将相应的dll文件复制过来。

对应这个例子,可以在帮助中通过Simple Text Viewer Example关键字查看。

QtAssistant的定制可以通过Customizing Qt Assistant关键字查看。The Qt HelpFramework关键字对应的文档中还讲解了使用QHelpEngine的 API将帮助内容直接嵌入到应用程序中,感兴趣的读者可以参考一下。

相关文章