리치 텍스트 문서 구조

텍스트 문서는 문서의 내부 표현과 구조에 대한 정보를 포함하고 실행 취소/다시 실행 기능을 제공하기 위해 수정 사항을 추적하는 QTextDocument 클래스로 표현됩니다.

텍스트 문서의 구조화된 표현은 텍스트 블록, 프레임, 표 및 기타 개체의 계층 구조로 내용을 표시합니다. 이는 문서에 논리적 구조를 제공하고 콘텐츠가 표시되는 방식을 설명합니다. 일반적으로 프레임과 표는 다른 구조를 그룹화하는 데 사용되며 텍스트 블록은 실제 텍스트 정보를 포함합니다.

새 요소는 QTextCursor를 사용하거나 QTextEdit 과 같은 편집기 위젯을 사용하여 프로그래밍 방식으로 생성하고 문서에 삽입합니다. 요소는 생성할 때 특정 형식을 지정할 수 있으며, 그렇지 않으면 커서의 현재 요소 형식을 사용합니다.

기본 구조

문서의 '최상위 레벨'은 표시된 방식으로 채워질 수 있습니다. 각 문서에는 항상 루트 프레임이 포함되며, 여기에는 항상 하나 이상의 텍스트 블록이 포함됩니다.

일부 텍스트 콘텐츠가 있는 문서의 경우 루트 프레임에는 일반적으로 일련의 블록 및 기타 요소가 포함됩니다.

프레임과 표의 시퀀스는 텍스트 블록에 정보가 포함되어 있지 않더라도 문서에서 항상 텍스트 블록으로 구분됩니다. 이렇게 하면 기존 구조 사이에 항상 새 요소를 삽입할 수 있습니다.

이 장에서는 서식 있는 텍스트 문서에 사용되는 각 구조 요소를 살펴보고, 그 기능과 용도를 간략하게 설명하고, 내용을 검토하는 방법을 보여 드립니다. 문서 편집은 QTextCursor 인터페이스에 설명되어 있습니다.

서식 있는 텍스트 문서

QTextDocument 객체에는 서식 있는 텍스트 문서를 구성하는 데 필요한 모든 정보가 포함되어 있습니다. 텍스트 문서는 편집자가 사용할 수 있는 선형 버퍼와 레이아웃 엔진에 유용한 객체 계층 구조라는 두 가지 상호 보완적인 방식으로 액세스할 수 있습니다. 계층적 문서 모델에서 객체는 일반적으로 프레임, 표, 목록과 같은 시각적 요소에 해당합니다. 하위 수준에서 이러한 요소는 텍스트 스타일 및 정렬과 같은 속성을 설명합니다. 문서의 선형적 표현은 문서 콘텐츠의 편집 및 조작에 사용됩니다.

QTextEdit 을 사용하면 서식 있는 텍스트를 쉽게 표시하고 편집할 수 있지만, 예를 들어 편집기 위젯과 관계없이 문서를 독립적으로 사용할 수도 있습니다:

QTextDocument *newDocument = new QTextDocument;

또는 기존 편집기에서 문서를 추출할 수도 있습니다:

QTextEdit *editor = new QTextEdit;
QTextDocument *editorDocument = editor->document();

이러한 유연성 덕분에 애플리케이션은 여러 개의 편집기 위젯을 사용하거나 문서를 중간 형식으로 저장할 필요 없이 여러 개의 서식 있는 텍스트 문서를 처리할 수 있습니다.

빈 문서에는 하나의 빈 텍스트 블록을 포함하는 루트 프레임이 포함되어 있습니다. 프레임은 문서의 각 부분을 논리적으로 구분할 뿐만 아니라 렌더링할 때 표시되는 방식을 결정하는 속성도 가지고 있습니다. 표는 행과 열로 배열된 여러 개의 셀로 구성된 특수한 유형의 프레임으로, 각 셀에는 추가 구조와 텍스트를 포함할 수 있습니다. 표는 셀을 유연하게 구성할 수 있는 관리 및 레이아웃 기능을 제공합니다.

텍스트 블록에는 텍스트 및 문자 형식 정보를 지정하는 텍스트 조각이 포함되어 있습니다. 텍스트 속성은 문자 수준과 블록 수준 모두에서 정의됩니다. 문자 수준에서는 글꼴 패밀리, 텍스트 색상 및 글꼴 굵기와 같은 속성을 지정할 수 있습니다. 블록 수준 속성은 텍스트 흐름 방향, 정렬 및 배경색과 같은 텍스트의 상위 수준 모양과 동작을 제어합니다.

문서 구조는 직접 조작할 수 없습니다. 편집은 커서 기반 인터페이스를 통해 수행됩니다. 텍스트 커서 인터페이스는 새 문서 요소를 루트 프레임에 자동으로 삽입하고 필요한 경우 빈 블록으로 채워집니다.

루트 프레임은 다음과 같은 방식으로 얻습니다:

    QTextDocument *editorDocument = editor->document();
    QTextFrame *root = editorDocument->rootFrame();

문서 구조를 탐색할 때는 전체 문서 구조에 대한 액세스를 제공하기 때문에 루트 프레임에서 시작하는 것이 유용합니다.

문서 요소

서식 있는 텍스트 문서는 일반적으로 단락, 프레임, 표 및 목록과 같은 일반적인 요소로 구성됩니다. 이러한 요소는 QTextBlock, QTextFrame, QTextTable, QTextList 클래스에 의해 QTextDocument 로 표현됩니다. 문서의 다른 요소와 달리 이미지는 특수한 형식의 텍스트 조각으로 표시됩니다. 따라서 주변 텍스트와 인라인으로 서식을 지정하여 배치할 수 있습니다.

문서의 기본 구조 빌딩 블록은 QTextBlockQTextFrame 입니다. 블록 자체에는 서식 있는 텍스트 조각(QTextFragment)이 포함되어 있지만 문서의 상위 구조에 직접적인 영향을 미치지는 않습니다.

다른 문서 요소를 함께 그룹화할 수 있는 요소는 일반적으로 QTextObject 의 하위 클래스이며 두 가지 범주에 속합니다: 텍스트 블록을 함께 그룹화하는 요소는 QTextBlockGroup 의 서브클래스이고 프레임 및 기타 요소를 함께 그룹화하는 요소는 QTextFrame 의 서브클래스입니다.

텍스트 블록

텍스트 블록은 QTextBlock 클래스에서 제공합니다.

텍스트 블록은 문자 형식이 다른 텍스트 조각을 그룹화하며 문서에서 단락을 나타내는 데 사용됩니다. 각 블록에는 일반적으로 서로 다른 스타일을 가진 여러 개의 텍스트 조각이 포함됩니다. 텍스트가 문서에 삽입될 때 조각이 생성되고 문서를 편집할 때 더 많은 조각이 추가됩니다. 문서는 조각을 분할, 병합 및 제거하여 블록에 있는 다양한 스타일의 텍스트를 효율적으로 표현합니다.

특정 블록 내의 조각은 QTextBlock::iterator 을 사용하여 블록의 내부 구조를 탐색하여 검사할 수 있습니다:

    QTextBlock::iterator it;
    for (it = currentBlock.begin(); !(it.atEnd()); ++it) {
        QTextFragment currentFragment = it.fragment();
        if (currentFragment.isValid())
            processFragment(currentFragment);
    }

블록은 목록 항목을 표현하는 데도 사용됩니다. 따라서 블록은 목록 항목에 사용되는 글머리 기호 유형과 같은 블록 수준 장식에 대한 정보를 포함하는 자체 문자 형식을 정의할 수 있습니다. 블록 자체의 서식은 QTextBlockFormat 클래스에 의해 설명되며 텍스트 정렬, 들여쓰기 및 배경색과 같은 속성을 설명합니다.

주어진 문서에 복잡한 구조가 포함되어 있더라도 문서에서 유효한 블록에 대한 참조만 있으면 각 텍스트 블록을 작성된 순서대로 탐색할 수 있습니다:

    QTextBlock currentBlock = textDocument->begin();

    while (currentBlock.isValid()) {
        processBlock(currentBlock);
        currentBlock = currentBlock.next();
    }

이 방법은 프레임, 표 및 기타 유형의 구조를 무시하므로 문서에서 서식 있는 텍스트만 추출하려는 경우에 유용합니다.

QTextBlock operator== () 및 operator!=()은 두 블록이 동일한지 테스트하는 데 사용되며 operator<()은 문서에서 어떤 블록이 먼저 나오는지 확인하는 데 사용됩니다.

프레임

프레임은 QTextFrame 클래스에서 제공합니다.

텍스트 프레임은 텍스트 블록과 하위 프레임을 함께 그룹화하여 단락보다 큰 문서 구조를 만듭니다. 프레임의 형식은 페이지에서 프레임이 렌더링되고 배치되는 방식을 지정합니다. 프레임은 텍스트 흐름에 삽입되거나 페이지의 왼쪽 또는 오른쪽에 떠 있습니다. 각 문서에는 다른 모든 문서 요소를 포함하는 루트 프레임이 포함되어 있습니다. 따라서 루트 프레임을 제외한 모든 프레임에는 상위 프레임이 있습니다.

텍스트 블록은 다른 문서 요소를 구분하는 데 사용되므로 각 프레임에는 항상 하나 이상의 텍스트 블록과 0개 이상의 하위 프레임이 포함됩니다. QTextFrame::iterator 을 사용하여 프레임의 하위 요소를 탐색하여 프레임의 콘텐츠를 검사할 수 있습니다:

    QTextFrame::iterator it;
    for (it = frame->begin(); !(it.atEnd()); ++it) {

        QTextFrame *childFrame = it.currentFrame();
        QTextBlock childBlock = it.currentBlock();

        if (childFrame)
            processFrame(childFrame);
        else if (childBlock.isValid())
            processBlock(childBlock);
    }

반복기는 프레임과 블록을 모두 선택하므로 어느 쪽을 참조하는지 확인해야 합니다. 이렇게 하면 프레임 단위로 문서 구조를 탐색하면서도 필요한 경우 텍스트 블록에 액세스할 수 있습니다. QTextBlock::iteratorQTextFrame::iterator 클래스는 모두 문서에서 필요한 구조를 추출하는 데 상호 보완적으로 사용할 수 있습니다.

표는 QTextTable 클래스에서 제공합니다.

표는 행과 열로 배열된 셀의 모음입니다. 각 표 셀은 고유한 문자 형식을 가진 문서 요소이지만 프레임 및 텍스트 블록과 같은 다른 요소도 포함할 수 있습니다. 표 셀은 표를 만들 때 또는 행이나 열이 추가될 때 자동으로 만들어집니다. 테이블 간에 이동할 수도 있습니다.

QTextTableQTextFrame 의 서브클래스이므로 문서 구조에서 표는 프레임처럼 취급됩니다. 문서에서 마주치는 각 프레임에 대해 테이블을 나타내는지 테스트하고 다른 방식으로 처리할 수 있습니다:

    QTextFrame::iterator it;
    for (it = frame->begin(); !(it.atEnd()); ++it) {

        QTextFrame *childFrame = it.currentFrame();
        QTextBlock childBlock = it.currentBlock();

        if (childFrame) {
            QTextTable *childTable = qobject_cast<QTextTable*>(childFrame);

            if (childTable)
                processTable(childTable);
            else
                processFrame(childFrame);

        } else if (childBlock.isValid()) {
            processBlock(childBlock);
        }
    }

기존 표 내의 셀은 행과 열을 반복하여 검사할 수 있습니다.

    for (int row = 0; row < table->rows(); ++row) {
        for (int column = 0; column < table->columns(); ++column) {
            QTextTableCell tableCell = table->cellAt(row, column);
            processTableCell(tableCell);
        }
    }

목록

목록은 QTextList 클래스에서 제공합니다.

목록은 일반적인 방식으로 서식이 지정되지만 글머리 기호 및 열거형 항목과 같은 표준 목록 장식을 제공하는 텍스트 블록의 시퀀스입니다. 목록은 중첩될 수 있으며 목록 형식이 0이 아닌 들여쓰기를 지정하는 경우 들여쓰기됩니다.

목록의 인덱스로 각 목록 항목을 참조할 수 있습니다:

    for (int index = 0; index < list->count(); ++index) {
        QTextBlock listItem = list->item(index);
        processListItem(listItem);
    }

QTextListQTextBlockGroup 의 서브클래스이므로 목록 항목을 하위 요소로 그룹화하지 않고 대신 목록 항목을 관리하기 위한 다양한 기능을 제공합니다. 즉, 문서를 탐색할 때 발견되는 모든 텍스트 블록이 실제로는 목록 항목일 수 있습니다. 다음 코드를 사용하여 목록 항목을 올바르게 식별할 수 있습니다:

    QTextFrame::iterator it;
    for (it = frame->begin(); !(it.atEnd()); ++it) {

        QTextBlock block = it.currentBlock();

        if (block.isValid()) {

            QTextList *list = block.textList();

            if (list) {
                int index = list->itemNumber(block);
                processListItem(list, index);
            }
        }
    }

이미지

QTextDocument 의 이미지는 리소스 메커니즘을 통해 외부 이미지를 참조하는 텍스트 조각으로 표시됩니다. 이미지는 커서 인터페이스를 사용하여 생성되며 나중에 이미지의 텍스트 조각의 문자 형식을 변경하여 수정할 수 있습니다:

    if (fragment.isValid()) {
        QTextImageFormat newImageFormat = fragment.charFormat().toImageFormat();

        if (newImageFormat.isValid()) {
            newImageFormat.setName(":/images/newimage.png");
            QTextCursor helper = cursor;

            helper.setPosition(fragment.position());
            helper.setPosition(fragment.position() + fragment.length(),
                                QTextCursor::KeepAnchor);
            helper.setCharFormat(newImageFormat);
        }
    }

이미지를 나타내는 조각은 이미지가 포함된 텍스트 블록의 조각을 반복하여 찾을 수 있습니다.

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