Home · All Classes · Main Classes · Grouped Classes · Modules · Functions

[Предыдущая: Система Рисования Arthur] [Начало] [Следующая: Классы Главного Окна в Qt 4]

Классы Работы с Текстом Scribe

Scribe предоставляет набор классов Qt 4 для размещения текста. Эти классы заменяют мощный текстовый движок Qt 3 и предоставляют новые возомжности обработки и размещения простого и форматированного текста.

Для более детального ознакомления с классами Scribe см. документ Обработка Форматированного Текста.

Обзор Scribe

Поддержка отображения и компоновки текста с Qt 4 была перепроектирована с использованием системы, позволяющей осуществлять эти действия более гибко, чем в Qt 3. Qt 4 также предоставляет более удобный интерфейс для программирования изменения документов. Эти усовершенствования были достигнуты с помощью переработки системы отрисовки текста и предоставления нескольких новых классов.

Далее следует краткий обзор основных концепций Scribe.

Интерфейс Документа

Текстовые документы скорее представлены классом QTextDocument, чем набором объектов QString. Каждый объект QTextDocument содержит информацию о внутреннем представлении документа, его структуре и отслеживает последовательность модификаций для поддержки возможностей отмены/повторения. Данный подход позволяет делегировать управление компоновкой классам-наследникам при сохранении центрального управления в одном классе.

Документы могут быть конвертированы из внешних источников или созданы на пустом мести с использованием Qt. Создание документа может быть осуществлено с помощью виджета-редактора, такого как QTextEdit или с помощью вызова API Scribe.

К текстовым документам можно обращаться двумя взаимодополняющими способами: как к линейному буферу (для редактирования и использования) и как к иерархической структуре (для управления компоновкой). В иерархической модели документа объекты, как правило, соответствуют визуальным элементам типа рамок, таблиц и списков. На низовом уровне эти элементы описывают такие атрибуты текста, как стиль и выравнивание. Линейное представление используется для редактирования и манипуляции содержимым документа.

Структура Документа

Каждый документ содержит корневую структуру в которую помещены все элементы.Коневая структура содержит такие структурные элементы как таблицы, блоки текста и т.д., которые могут иметь произовольную глубину вложения.

Структура не только представляет логическую организацию документа, но и содержит свойтсва, влияющие на отрисовку текста. Таблица - это специализированный элемент, состоящий из ячеек расположенных в виде строк и столбцов и содержащих структуры более низкого уровня или текст. Таблицы обеспечивают управление расположением с помощью создания гибких конфигураций ячеек.

Текстовые блоки содержат сам текст и признаки его форматирования. Свойста текста можно задавать как для символа, так и для блока целиком. На уровне символа могут быть определены такие свойства как начертание и размер шрифта, а также цвет символов. Свойства текстового блока управляют более глобальными особенностями текста, такими как: выравнивание текста, его направления и фонового цвета.

Структура документа не имеет непосредственного управления. Управление производится через интерфейс на основе курсоров.

Создание Содержимого Документа и Его Редактирование

Документы могут быть отредактированы через интерфейс предоставленный классом QTextCursor, курсоров, созданы с при помощи конструкторов или получены от виджетов-редакторов. Курсор используется для выполнения таких действий по редактированию, которые пользователь осуществляет сам работая в редакторе. В результате информация о структуре документа также становится доступна и может быть изменена. Использование интерфейса ориентированного на курсор делает более простым процесс отображения пользовательского текста, так как он (процесс) может быть легко визуализирован.

Класс QTextCursor также содержит информацию о выделенном в документе тексте и поддерживает возможности работы с выделенным текстом подобно возможностям работы пользователя в текстовом редакторе.

Компоновка Документа

Управление компоновкой уместно лишь когда документ должен быть отображен на некотором устройстве или когда требуются некоторые сведения для визуализации информации о документе. Пока этого не происходит, документ не может быть отформатирован и подготовлен для отображения.

Компоновкой каждого документа управляет подкласс QAbstractTextDocumentLayout. Этот класс предоставляет общий интерфейс для движков компоновки и отображения. По умолчанию процесс отрисовки реализован в частном классе. Такой подход делает возможным создание собственных компоновщиков и предоставляет механизм, используемый при подготовки страниц для печати или экспорта в файлы Portable Document Format (PDF).

Примеры Кода

Здесь представлены два способа, использования Scribe: для создания и манипулирования форматированным текстом и для размещения простого текста.

Манипулирование Форматированным Текстом

Форматированный текст хранится в текстовых документах, которые могут быть созданы импортированием HTML из внешних источников или созданы с помощью QTextCursor. Самый легкий способ использования форматированного текстового документа - это использование класса QTextEdit обеспечивающего отображение и возможность редактирования документа. Код приведенный ниже импортирует документ HTML в текстовый документ и отображает текстовый документ в виджете позволяющем редактировать текст.

        QTextEdit *editor = new QTextEdit(parent);
        editor->setHtml(aStringContainingHTMLtext);
        editor->show();

Вы можете получить указатель на текстовый документ от тестового редактора с помощью функции document(). После этого документ можно изменить программно использую класс QTextCursor. Этот класс работает по принципу экранного курсора, а операции редактирования отображаются на экране. Следующий код изменяет начертание шрифта первой строки на полужирное оставляя все другие характеристики нетронутыми. Редактор автоматически обновится для отображения сделанных изменений.

        QTextDocument *document = edit->document();
        QTextCursor cursor(document);

        cursor.movePosition(QTextCursor::Start);
        cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);

        QTextCharFormat format;
        format.setFontWeight(QFont::Bold);

        cursor.mergeCharFormat(format);

Обратите внимание на то, что курсор был перемещен от начала линии к концу и при этом сохранилась привязка к началу линии. Это показывает средства для работы с классом QTextCursor.

Используя подход на основе курсора можно очень быстро создать форматированный текст. Следующий пример отображает календарь в виджете QTextEdit с полужирными заголовками дней недели:

        editor = new QTextEdit(this);

        QTextCursor cursor(editor->textCursor());
        cursor.movePosition(QTextCursor::Start);

        QTextCharFormat format(cursor.charFormat());
        format.setFontFamily("Courier");

        QTextCharFormat boldFormat = format;
        boldFormat.setFontWeight(QFont::Bold);

        cursor.insertBlock();
        cursor.insertText(" ", boldFormat);

        QDate date = QDate::currentDate();
        int year = date.year(), month = date.month();

        for (int weekDay = 1; weekDay <= 7; ++weekDay) {
            cursor.insertText(QString("%1 ").arg(QDate::shortDayName(weekDay), 3),
                boldFormat);
        }

        cursor.insertBlock();
        cursor.insertText(" ", format);

        for (int column = 1; column < QDate(year, month, 1).dayOfWeek(); ++column) {
            cursor.insertText("    ", format);
        }

        for (int day = 1; day <= date.daysInMonth(); ++day) {
            int weekDay = QDate(year, month, day).dayOfWeek();

            if (QDate(year, month, day) == date)
                cursor.insertText(QString("%1 ").arg(day, 3), boldFormat);
            else
                cursor.insertText(QString("%1 ").arg(day, 3), format);

            if (weekDay == 7) {
                cursor.insertBlock();
                cursor.insertText(" ", format);
            }
        }

Вышеприведенный пример демонстрирует насколько просто создается форматированный текст и как мало для этого нужно кодировать. Хотя для минимизации кода мы отобразили простой неизменный календарь, Scribe предоставляет возможности более сложной компоновки и форматирования текста.

Компоновка Простого Текста

Иногда важно иметь возможность расположения текста в пределах изменяющейся области, например, при отрисовке собственноручно созданного виджета. Scribe предоставляет возможность для обтекания текстом и расположения текста без потребности создания документа с начала.

Отображение простого текста обычно осуществляется вдоль прямых линий. Пример приведенный ниже расположит простой текст вдоль внешней кромки правой части круги используя обычный шрифт.

        QTextLayout textLayout(text, font);
        qreal margin = 10;
        qreal radius = qMin(width()/2.0, height()/2.0) - margin;
        QFontMetrics fm(font);

        qreal lineHeight = fm.height();
        qreal y = 0;

        textLayout.beginLayout();

        while (1) {
            // create a new line
            QTextLine line = textLayout.createLine();
            if (!line.isValid())
                break;

            qreal x1 = qMax(0.0, pow(pow(radius,2)-pow(radius-y,2), 0.5));
            qreal x2 = qMax(0.0, pow(pow(radius,2)-pow(radius-(y+lineHeight),2), 0.5));
            qreal x = qMax(x1, x2) + margin;
            qreal lineWidth = (width() - margin) - x;

            line.setLineWidth(lineWidth);
            line.setPosition(QPointF(x, margin+y));
            y += line.height();
        }

        textLayout.endLayout();

        QPainter painter;
        painter.begin(this);
        painter.setRenderHint(QPainter::Antialiasing);
        painter.fillRect(rect(), Qt::white);
        painter.setBrush(QBrush(Qt::black));
        painter.setPen(QPen(Qt::black));
        textLayout.draw(&painter, QPoint(0,0));

        painter.setBrush(QBrush(QColor("#a6ce39")));
        painter.setPen(QPen(Qt::black));
        painter.drawEllipse(QRectF(-radius, margin, 2*radius, 2*radius));
        painter.end();

Мы создаем компоновку текста определяя строку, которую мы хотим показать и шрифт. Мы добиваемся правильного расположения текста получая линии текста от объекта форматирования и располагаем текст в предоставленном пространстве. Линии позиционируются горизонтально и вертикально поскольку мы смещаемся вниз по странице.

Форматированный текст может быть отображен на устройстве; в вышеприведенном примере форматированный текст отображет на виджете.

Особенности Печати

Система компоновки, предназначенная для работы с форматированным текстом, также поддерживает и компоновку документа с разбиением по страницам, что используется Qt для создания заданий для печати. Процедура печати выполняется QPrinter и управляется пользователем через настройки, отображаемые в QPrintDialog:

        QTextDocument *document = editor->document();
        QPrinter printer;

        QPrintDialog *dlg = new QPrintDialog(&printer, this);
        if (dlg->exec() != QDialog::Accepted)
            return;

        document->print(&printer);

Форматированные текстовые документы также, с помощью QPrinter и соответствующего движка печати, могут экспортироваться как файлы PDF:

        QPrinter printer(QPrinter::HighResolution);
        printer.setFullPage(true);
        QPrintDialog *dlg = new QPrintDialog(&printer, this);
        if (dlg->exec() == QDialog::Accepted) {
            textEdit->document()->print(&printer);

Сравнение с Qt 3

Возможности основанного на курсорах редактирования объединенные со структурной моделью документа предоставляют мощный набор инструментов для редактирования и отображения форматированного текста. Они обеспечивают возможности которые были недоступны в открытых API Qt 3. Используемы текстовый движок полностью переписан и не использует текстовый движок Qt 3.

Класс QTextEdit в Qt 4 полностью переписан и имеет API существенно отличный от своего коллеги в Qt 3. Неокоторые методы оставлены для совместимости со стилем программирования виджетов знакомым пользователям Qt 3. Данный класс является полным примером виджета-редактора с новым API, демонстрируя возможности редактирования основанного на интерфейсе редактирования QTextCursor.

[Предыдущая: Система Рисования Arthur] [Начало] [Следующая: Классы Главного Окна в Qt 4]


Copyright © 2005 Trolltech Trademarks
Qt 4.1.0
Hosted by uCoz