En esta página

Ejemplo de visor de texto simple

Uso de Qt Assistant como visor de ayuda personalizado para su aplicación.

Captura de pantalla de la interfaz de usuario de ejemplo del visor de texto simple.

Este ejemplo muestra cómo utilizar Qt Assistant como visor de ayuda personalizado en una aplicación personalizada. Esto se hace en dos etapas. En primer lugar, se crea la documentación y se personaliza Qt Assistant; en segundo lugar, se añade a la aplicación la funcionalidad para lanzar y controlar Qt Assistant.

La aplicación Simple Text Viewer permite al usuario seleccionar y visualizar los archivos existentes. La aplicación proporciona su propia documentación personalizada que está disponible en el menú Ayuda de la barra de menús de la ventana principal o haciendo clic en el botón Ayuda del cuadro de diálogo de búsqueda de archivos de la aplicación.

El ejemplo consta de cuatro clases:

  • Assistant proporciona funcionalidad para lanzar Qt Assistant.
  • MainWindow es la ventana principal de la aplicación.
  • FindFileDialog permite al usuario buscar archivos utilizando comodines.
  • TextEdit proporciona un navegador de texto enriquecido que se asegura de que las imágenes referenciadas en documentos HTML se muestran correctamente.

Nota: Sólo comentaremos las partes de la implementación que son relevantes para el tema principal, que es hacer que Qt Assistant actúe como un visor de ayuda personalizado para nuestra aplicación Simple Text Viewer.

Creación de la documentación y personalización Qt Assistant

Cómo crear la documentación real en forma de páginas HTML no entra en el ámbito de este ejemplo. En general, las páginas HTML pueden ser escritas a mano o generadas con la ayuda de herramientas de documentación como qdoc o Doxygen. Para los propósitos de este ejemplo asumimos que los archivos HTML ya han sido creados. Por lo tanto, lo único que queda por hacer es indicar a Qt Assistant cómo estructurar y mostrar la información de ayuda.

Organizar la documentación para Qt Assistant

Los archivos HTML planos sólo contienen texto o documentación sobre temas específicos, pero normalmente no incluyen información sobre cómo se relacionan varios documentos HTML entre sí o en qué orden se supone que deben leerse. Lo que falta es una tabla de contenidos junto con un índice para acceder rápidamente a determinados contenidos de ayuda, sin tener que navegar por un montón de documentos para encontrar una información.

Para organizar la documentación y ponerla a disposición de Qt Assistant, tenemos que crear un archivo de proyecto de ayuda Qt (.qhp). La primera y más importante parte del archivo de proyecto es la definición del espacio de nombres. El espacio de nombres tiene que ser único y será la primera parte de la URL de la página en Qt Assistant. Además, tenemos que establecer una carpeta virtual que actúe como carpeta común para los conjuntos de documentación. Esto significa que dos conjuntos de documentación identificados por dos espacios de nombres diferentes pueden hacer referencia cruzada a archivos HTML, ya que dichos archivos se encuentran en una gran carpeta virtual. Sin embargo, para este ejemplo, sólo tendremos un conjunto de documentación disponible, por lo que el nombre de la carpeta virtual y su funcionalidad no son importantes.

<?xml version="1.0" encoding="UTF-8"?>
<QtHelpProject version="1.0">
  <namespace>org.qt-project.examples.simpletextviewer</namespace>
  <virtualFolder>doc</virtualFolder>

El siguiente paso es definir la sección de filtrado. Una sección de filtrado contiene la tabla de contenidos, los índices y una lista completa de todos los archivos de documentación, y puede tener asignados cualquier número de atributos de filtrado. Un atributo de filtro es una cadena ordinaria que puede elegirse libremente. Más adelante, en Qt Assistant, los usuarios pueden definir un filtro personalizado que haga referencia a esos atributos. Si los atributos de una sección de filtro coinciden con los atributos del filtro personalizado, se mostrará la documentación; de lo contrario, Qt Assistant ocultará la documentación.

De nuevo, dado que sólo tendremos un conjunto de documentación, no necesitamos la funcionalidad de filtrado de Qt Assistant y, por tanto, podemos omitir los atributos del filtro.

Ahora, construimos la tabla de contenidos. Un elemento de la tabla se define mediante la etiqueta section, que contiene los atributos para el título del elemento, así como el enlace a la página real. Las etiquetas de sección pueden anidarse infinitamente, pero por razones prácticas no se recomienda anidarlas a más de tres o cuatro niveles. Para nuestro ejemplo queremos utilizar el siguiente esquema para la tabla de contenidos:

  • Visor de texto simple
    • Buscar archivo
      • Diálogo de archivo
      • Coincidencia de comodines
      • Explorar
    • Abrir archivo

En el archivo del proyecto de ayuda, el esquema está representado por:

<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>

Una vez definido el índice, listaremos todas las palabras clave del índice:

<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>

Como último paso, tenemos que enumerar todos los archivos que componen la documentación. Un punto importante a tener en cuenta aquí es que todos los archivos tienen que ser listados, incluyendo los archivos de imagen, e incluso las hojas de estilo si se utilizan.

    <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>

El archivo del proyecto de ayuda ya está terminado. Si quieres ver la documentación resultante en Qt Assistant, tienes que generar un archivo de ayuda comprimido Qt a partir de él y registrarlo con la colección de ayuda por defecto de Qt Assistant.

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

Si inicias Qt Assistant ahora, verás la documentación del Visor de Texto Simple junto a la documentación de Qt. Esto está bien para propósitos de prueba, pero para la versión final queremos tener sólo la documentación del Visor de Texto Simple en Qt Assistant.

Personalizando Qt Assistant

La forma más sencilla de hacer que Qt Assistant sólo muestre la documentación del Visor de texto simple es crear nuestro propio archivo de colección de ayuda. Un archivo de colección se almacena en formato binario, similar al archivo de ayuda comprimido, y se genera a partir de un archivo de proyecto de colección de ayuda (*.qhcp). Con la ayuda de un archivo de colección, podemos personalizar la apariencia e incluso algunas funcionalidades que ofrece Qt Assistant.

Al principio, cambiamos el título y el icono de la ventana. En lugar de mostrar "Qt Assistant" mostrará "Simple Text Viewer", de forma que quede mucho más claro para el usuario que el visor de ayuda pertenece realmente a nuestra aplicación.

<?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>

La etiqueta cacheDirectory especifica un subdirectorio del directorio de datos del usuario (véase la colección de archivosQt Help ) donde se almacenará el archivo de caché para la búsqueda de texto completo o el archivo de configuración.

Después de esto, establecemos la página mostrada por Qt Assistant cuando se lanza por primera vez en su nueva configuración. La URL consiste en el espacio de nombres y la carpeta virtual definidos en el archivo de proyecto de la ayuda Qt, seguidos por el nombre real del archivo de la página.

<startPage>qthelp://org.qt-project.examples.simpletextviewer/doc/index.html</startPage>

A continuación, cambiamos el nombre de la opción de menú "Acerca de" por "Acerca de Simple Text Viewer". El contenido del cuadro de diálogo Acerca de también se modifica especificando un archivo del que se toma el texto o el icono Acerca de.

<aboutMenuText>
    <text>About Simple Text Viewer</text>
</aboutMenuText>
<aboutDialog>
    <file>about.txt</file>
    <icon>images/icon.png</icon>
</aboutDialog>

Qt Assistant ofrece la posibilidad de añadir o eliminar documentación a través de su diálogo de preferencias. Esta funcionalidad es útil cuando se utiliza Qt Assistant como visor central de ayuda para más aplicaciones, pero en nuestro caso queremos evitar que el usuario elimine la documentación. Por lo tanto, ocultamos la pestaña Documentación en el cuadro de diálogo Preferencias.

Como la barra de direcciones no es realmente relevante en un conjunto de documentación tan pequeño, también la desactivamos. Al tener sólo una sección de filtro, sin ningún atributo de filtro, también podemos desactivar la funcionalidad de filtro de Qt Assistant, lo que significa que la página de filtro y la barra de herramientas de filtro no estarán disponibles.

    <enableDocumentationManager>false</enableDocumentationManager>
    <enableAddressBar>false</enableAddressBar>
    <enableFilterFunctionality>false</enableFilterFunctionality>
</assistant>

A efectos de prueba, ya hemos generado el archivo de ayuda comprimido y lo hemos registrado en la colección de ayuda por defecto de Qt Assistant. Con las siguientes líneas conseguimos el mismo resultado. La única e importante diferencia es que registramos el fichero de ayuda comprimido, no en la colección por defecto, sino en nuestro propio fichero de colección.

  <docFiles>
    <generate>
        <file>
            <input>simpletextviewer.qhp</input>
            <output>simpletextviewer.qch</output>
            </file>
        </generate>
    <register>
        <file>simpletextviewer.qch</file>
        </register>
    </docFiles>
</QHelpCollectionProject>

Como último paso, tenemos que generar el fichero binario de la colección a partir del fichero de proyecto de la colección de ayuda. Esto se hace ejecutando la herramienta qhelpgenerator.

qhelpgenerator simpletextviewer.qhcp -o simpletextviewer.qhc

Para probar todas nuestras personalizaciones hechas a Qt Assistant, añadimos el nombre del archivo de colección a la línea de comandos:

assistant -collectionFile simpletextviewer.qhc

Controlando Qt Assistant a través de la Clase Asistente

Primero veremos como iniciar y operar Qt Assistant desde una aplicación remota. Para ello, creamos una clase llamada Assistant.

Esta clase proporciona una función pública que se utiliza para mostrar páginas de la documentación, y una función privada de ayuda para asegurarse de que Qt Assistant está en funcionamiento.

El lanzamiento de Qt Assistant se realiza en la función startAssistant() simplemente creando e iniciando un QProcess. Si el proceso ya esta corriendo, la funcion retorna inmediatamente. Si no, el proceso tiene que ser creado e iniciado.

bool Assistant::startAssistant()
{
    if (m_process.isNull()) {
        m_process.reset(new QProcess);
        QObject::connect(m_process.data(), &QProcess::finished,
                         m_process.data(), [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;
}

Para iniciar el proceso necesitamos el nombre ejecutable de Qt Assistant así como los argumentos de línea de comandos para ejecutar Qt Assistant en modo personalizado. El nombre del ejecutable es un poco complicado ya que depende de la plataforma, pero afortunadamente sólo es diferente en macOS.

La documentación mostrada puede modificarse utilizando el argumento de línea de comandos -collectionFile al iniciar Qt Assistant. Cuando se inicia sin ninguna opción, Qt Assistant muestra un conjunto de documentación por defecto. Cuando Qt está instalado, el conjunto de documentación por defecto en Qt Assistant contiene la documentación de referencia de Qt, así como las herramientas que vienen con Qt, como Qt Designer y qmake.

En nuestro ejemplo, reemplazamos el conjunto de documentación por defecto con nuestra documentación personalizada pasando nuestro archivo de colección específico de la aplicación a las opciones de línea de comandos del proceso.

Como último argumento, añadimos -enableRemoteControl, que hace que Qt Assistant escuche su canal stdin en busca de órdenes, como las de mostrar una determinada página de la documentación. A continuación, iniciamos el proceso y esperamos a que se ejecute realmente. Si, por alguna razón Qt Assistant no puede iniciarse, startAssistant() devolverá false.

La implementación de showDocumentation() es sencilla. En primer lugar, nos aseguramos de que Qt Assistant se está ejecutando, luego enviamos la solicitud para mostrar page a través del canal stdin del proceso. Es muy importante que el comando termine con un token de fin de línea para vaciar el canal.

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');
}

Finalmente, nos aseguramos de que Qt Assistant se termina correctamente en el caso de que la aplicación se cierre. El destructor de QProcess mata el proceso, lo que significa que la aplicación no tiene posibilidad de hacer cosas como guardar la configuración del usuario, lo que resultaría en archivos de configuración corruptos. Para evitar esto, pedimos a Qt Assistant que termine en el destructor de la clase Assistant.

Assistant::~Assistant()
{
    if (!m_process.isNull() && m_process->state() == QProcess::Running) {
        QObject::disconnect(m_process.data(), &QProcess::finished, nullptr, nullptr);
        m_process->terminate();
        m_process->waitForFinished(3000);
    }
}

Clase MainWindow

Captura de pantalla del visor de texto mostrando el menú de ayuda en la barra de pestañas

La clase MainWindow proporciona la ventana principal de la aplicación con dos menús: el menú Archivo permite al usuario abrir y ver un archivo existente, mientras que el menú Ayuda proporciona información sobre la aplicación y sobre Qt, y permite al usuario abrir Qt Assistant para mostrar la documentación de la aplicación.

Para poder acceder a la funcionalidad de ayuda, inicializamos el objeto Assistant en el constructor de MainWindow.

MainWindow::MainWindow()
    : textViewer(new TextEdit)
    , assistant(new Assistant)
{
    ...
}

A continuación creamos todas las acciones de la aplicación Visor de texto simple. De especial interés es la acción assistantAct accesible a través del atajo de teclado F1 o la opción de menú Ayuda > Contenido de la ayuda. Esta acción está conectada a la ranura showDocumentation() de la clase MainWindow.

void MainWindow::createActions()
{
    assistantAct = new QAction(tr("Help Contents"), this);
    assistantAct->setShortcut(QKeySequence::HelpContents);
    connect(assistantAct, &QAction::triggered, this, &MainWindow::showDocumentation);
    ...
}

En la ranura showDocumentation(), llamamos a la función showDocumentation() de la clase Assistant con la URL de la página de inicio de la documentación.

void MainWindow::showDocumentation()
{
    assistant->showDocumentation("index.html");
}

Finalmente, debemos reimplementar el manejador de evento protegido QWidget::closeEvent() para asegurarnos de que la instancia Qt Assistant de la aplicación se cierra correctamente antes de terminar la aplicación.

void MainWindow::closeEvent(QCloseEvent *)
{
    delete assistant;
}

Clase FindFileDialog

Captura de pantalla del cuadro de diálogo de búsqueda de archivos que muestra las opciones para introducir el nombre del archivo y el directorio en el que se debe buscar.

La aplicación Visor de Texto Simple proporciona un diálogo de búsqueda de archivos que permite al usuario buscar archivos utilizando comodines. La búsqueda se realiza dentro del directorio especificado, y al usuario se le da la opción de navegar por el sistema de archivos existente para encontrar el directorio relevante.

En el constructor guardamos las referencias a los objetos Assistant y QTextEdit pasados como argumentos. El objeto Assistant se utilizará en el slot FindFileDialog's help(), como veremos en breve, mientras que el QTextEdit se utilizará en el slot openFile() del diálogo para mostrar el fichero elegido.

FindFileDialog::FindFileDialog(TextEdit *editor, Assistant *assistant)
    : QDialog(editor)
    , currentEditor(editor)
    , currentAssistant(assistant)
{
    ...
}

El miembro más relevante a observar en la clase FindFileDialog es la ranura privada help(). La ranura está conectada al botón de Ayuda del diálogo, y trae la instancia actual Qt Assistant al primer plano con la documentación del diálogo llamando a la función showDocumentation() de Assistant.

void FindFileDialog::help()
{
    currentAssistant->showDocumentation("filedialog.html");
}

Resumen

Para hacer que Qt Assistant actúe como una herramienta de ayuda personalizada para su aplicación, debe proporcionar a su aplicación un proceso que controle Qt Assistant además de un archivo de colección de ayuda personalizada que incluya archivos de ayuda comprimidos Qt.

Para obtener más información sobre las opciones y la configuración disponibles para las aplicaciones que utilizan Qt Assistant como visor de ayuda personalizada, consulte Personalización de Qt Assistant.

Proyecto de ejemplo @ code.qt.io

© 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.