이 페이지에서

간단한 텍스트 뷰어 예제

Qt Assistant 를 응용 프로그램용 맞춤형 도움말 뷰어로 사용하는 방법.

Simple Text Viewer 예제 UI의 스크린샷.

이 예제는 사용자 정의 애플리케이션에서 Qt Assistant 을 맞춤형 도움말 뷰어로 사용하는 방법을 보여줍니다. 이 과정은 두 단계로 진행됩니다. 첫째, 문서를 작성하고 Qt Assistant 을 사용자 정의하며, 둘째, 애플리케이션을 실행하고 제어하는 기능을 Qt Assistant 에 추가합니다.

Simple Text Viewer 애플리케이션은 사용자가 기존 파일을 선택하고 볼 수 있게 해줍니다. 이 애플리케이션은 메인 창 메뉴 모음의 ‘도움말’ 메뉴나 애플리케이션의 파일 찾기 대화 상자에서 ‘도움말’ 버튼을 클릭하여 확인할 수 있는 자체 맞춤형 문서를 제공합니다.

이 예제는 네 개의 클래스로 구성되어 있습니다:

  • Assistant Qt Assistant 을 실행하는 기능을 제공합니다.
  • MainWindow 는 메인 애플리케이션 창입니다.
  • FindFileDialog 사용자가 와일드카드 일치를 사용하여 파일을 검색할 수 있게 해줍니다.
  • TextEdit HTML 문서에서 참조된 이미지가 올바르게 표시되도록 보장하는 리치 텍스트 브라우저를 제공합니다.

참고: 본 예제에서는 주요 문제, 즉 Qt Assistant 를 Simple Text Viewer 애플리케이션용 맞춤형 도움말 뷰어로 작동하도록 만드는 것과 관련된 구현 부분만설명하겠습니다 .

문서 작성 및 사용자 지정 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 태그로 정의되며, 이 태그에는 항목 제목에 대한 속성과 실제 페이지로 연결되는 링크가 포함됩니다. 섹션 태그는 무한히 중첩될 수 있지만, 실용적인 이유로 3~4단계 이상 깊게 중첩하는 것은 권장되지 않습니다. 이 예제에서는 목차에 다음과 같은 개요를 사용하고자 합니다:

  • 간단한 텍스트 뷰어
    • 파일 찾기
      • 파일 대화 상자
      • 와일드카드 일치
      • 찾아보기
    • 파일 열기

도움말 프로젝트 파일에서 개요는 다음과 같이 표현됩니다:

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

다음으로, “About” 메뉴 항목의 이름을 “About 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 는 환경 설정 대화 상자를 통해 문서를 추가하거나 제거할 수 있는 기능을 제공합니다. 이 기능은 를 여러 애플리케이션의 중앙 도움말 뷰어로 사용할 때 유용하지만, 우리의 경우 사용자가 문서를 제거하지 못하도록 막고자 합니다. 따라서 환경 설정 대화 상자에서 ‘문서(Documentation )’ 탭을 숨깁니다.

이처럼 작은 문서 세트에서는 주소 표시줄이 그다지 관련이 없으므로 이 역시 비활성화합니다. 필터 속성이 없는 필터 섹션을 하나만 두면 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 가 정상적으로 실행 중인지 확인하는 비공개 헬퍼 함수 하나를 제공합니다.

Qt Assistant 을 실행하는 작업은 startAssistant() 함수 내에서 QProcess를 생성하고 시작하는 간단한 방식으로 이루어집니다. 프로세스가 이미 실행 중이라면 함수는 즉시 반환됩니다. 그렇지 않은 경우, 프로세스를 설정하고 시작해야 합니다.

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 Designer 및 qmake 와 같이 Qt와 함께 제공되는 도구들도 포함되어 있습니다.

이 예제에서는 애플리케이션 전용 컬렉션 파일을 프로세스의 명령줄 옵션에 전달하여 기본 문서 세트를 사용자 정의 문서로 대체합니다.

마지막 인수로 -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 클래스는 메인 애플리케이션 창에 두 가지 메뉴를 제공합니다. ‘파일(File )’ 메뉴를 통해 사용자는 기존 파일을 열고 볼 수 있으며, ‘도움말 ( Help )’ 메뉴는 애플리케이션 및 Qt에 대한 정보를 제공하고, 사용자가 Qt Assistant 을 열어 애플리케이션 문서를 볼 수 있게 해줍니다.

도움말 기능을 사용할 수 있도록 하기 위해, MainWindow 의 생성자에서 Assistant 객체를 초기화합니다.

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

그런 다음 Simple Text Viewer 애플리케이션의 모든 액션을 생성합니다. 특히 주목할 만한 것은 F1 단축키나 ‘도움말 > 도움말 목차’ 메뉴 항목을 통해 접근할 수 있는 ‘ assistantAct ’ 액션입니다. 이 액션은 MainWindow 클래스의 showDocumentation() 슬롯에 연결되어 있습니다.

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

showDocumentation() 슬롯에서는 문서의 홈 페이지 URL을 인수로 전달하여 Assistant 클래스의 showDocumentation() 함수를 호출합니다.

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

마지막으로, 애플리케이션을 종료하기 전에 애플리케이션의 Qt Assistant 인스턴스가 올바르게 닫히도록 보장하기 위해 protected QWidget::closeEvent() 이벤트 핸들러를 재구현해야 합니다.

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

FindFileDialog 클래스

파일 이름을 입력하고 검색할 디렉터리를 지정할 수 있는 옵션이 표시된 ‘파일 찾기’ 대화 상자의 스크린샷

Simple Text Viewer 애플리케이션은 사용자가 와일드카드 일치를 사용하여 파일을 검색할 수 있는 파일 찾기 대화 상자를 제공합니다. 검색은 지정된 디렉터리 내에서 수행되며, 사용자는 기존 파일 시스템을 탐색하여 관련 디렉터리를 찾을 수 있는 옵션을 제공합니다.

생성자에서는 인수로 전달된 ` 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 Help 압축 도움말 파일이 포함된 사용자 정의 도움말 컬렉션 파일 외에도 Qt Assistant 를 제어하는 프로세스를 애플리케이션에 제공해야 합니다.

Qt Assistant 를 사용자 정의 도움말 뷰어로 사용하는 애플리케이션에서 사용할 수 있는 옵션 및 설정에 대한 자세한 내용은 Qt Assistant 사용자 정의를 참조하십시오.

예제 프로젝트 @ 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.