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

[Предыдущая: Модуль Работы с Сетью в Qt 4] [Начало] [Следующая: Поддержка Потоков в Qt 4]

API Стиля в Qt 4

API стиля в Qt предназначены для выполнения операций отрисовки встроенных виджетов. API стиля в Qt 4 был пересмотрен для того, чтобы можно было выполнять операции рисования виджетов без вызова любых функций виджетов.

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

Общий Обзор

Класс QStyle - это абстрактный базовый класс инкапсулирующий внешний вид и поведение элементов GUI. Встроенные виджеты Qt используют его для выполнения почти всех операций рисования, гарантируя сходство с аналогичными родными виджетами.

Сейчас большинство функций рисования принимают четыре аргумента:

Стиль получает всю информацию, которая требуется для отображения графического элемента, из QStyleOption. Виджет передают в последнем аргументе в том случае, если стиль нуждается в нем для создания специальных эффектов (типа анимированной кнопки по умолчанию в Mac OS X), но это не обязательно. Фактически, QStyle можно использовать для рисования на любых устройсвах рисования, а не только виджетах, специально настроив QPainter.

Благодаря QStyleOption, QStyle теперь может выполнять отрисовку виджетов в любом месте кода без установления связи с виджетом. Это похоже на то, как виджеты Qt 3 встроенных в Qt типов, такие как Q3ListView могут рисоваться без установления связи с библиотекой Qt3Support. Другая выгода нового подхода в том, что QStyle доступен для рисования виджетов отличных от встроенных; например, Вы можете нарисовать выпадающий список на любом виджете, а не только на QComboBox.

QStyleOption имеет различные подклассы для рисования графических элементов различных типов. Также можно создавать собственные подклассы. Например, элемент QStyle::PE_FrameFocusRect принимает аргумент QStyleOptionFocusRect. Данная информация описана для любого значения перечисления.

При повторной реализации функций QStyle принимающих параметр QStyleOption, часто нужно преобразовать QStyleOption к подклассу (например QStyleOptionFocusRect). Для того, чтобы гарантировать безопасность этой операции, Вы можете использовать qstyleoption_cast() для преобразования типа указателя. Если объект недопустимого типа, qstyleoption_cast() возвратит 0. Например:

    const QStyleOptionFocusRect *focusRectOption =
            qstyleoption_cast<const QStyleOptionFocusRect *>(option);
    if (focusRectOption) {
        ...
    }

По определенным причинам, класс предоставляет небольшое число функций-членов и прямой доступ к переменным. Такая "низкоуровневая" реализация заставляет напрямую использовать структуру и подчеркиевает, что это просто параметры используемые функциями стиля. Вызывающий функции QStyle обычно создает объект QStyleOption в стеке. Совместно с неявным разделением Qt таких типов как QString, QPalette и QColor гарантирует от напрасного расходования памяти. (Динамическое распределение памяти может быть дорогой операцией, особенно при частой перерисовке в которком времени.)

Пример Кода

Следующий код иллюстрирует как использовать QStyle для рисования прямоугольника в фокусе для собственного виджета по событию paintEvent():

    void MyWidget::paintEvent(QPaintEvent *event)
    {
        QPainter painter(this);
        ...

        QStyleOptionFocusRect option(1);
        option.init(this);
        option.backgroundColor = palette().color(QPalette::Background);

        style().drawPrimitive(QStyle::PE_FrameFocusRect, &option, &painter,
                              this);
    }

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

    class CustomStyle : public QWindowsStyle
    {
        Q_OBJECT

    public:
        CustomStyle() {}
        ~CustomStyle() {}

        void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
                           QPainter *painter, const QWidget *widget) const;
    };

    void CustomStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
                                    QPainter *painter, const QWidget *widget) const
    {
        if (element == PE_IndicatorSpinUp || element == PE_IndicatorSpinDown) {
            QPointArray points(3);
            int x = option->rect.x();
            int y = option->rect.y();
            int w = option->rect.width() / 2;
            int h = option->rect.height() / 2;
            x += (option->rect.width() - w) / 2;
            y += (option->rect.height() - h) / 2;

            if (element == PE_IndicatorSpinUp) {
                points[0] = QPoint(x, y + h);
                points[1] = QPoint(x + w, y + h);
                points[2] = QPoint(x + w / 2, y);
            } else { // PE_SpinBoxDown
                points[0] = QPoint(x, y);
                points[1] = QPoint(x + w, y);
                points[2] = QPoint(x + w / 2, y + h);
            }

            if (option->state & Style_Enabled) {
                painter->setPen(option->palette.mid().color());
                painter->setBrush(option->palette.buttonText());
            } else {
                painter->setPen(option->palette.buttonText().color());
                painter->setBrush(option->palette.mid());
            }
            painter->drawPolygon(points);
        } else {
            QWindowsStyle::drawPrimitive(element, option, painter, widget);
        }
    }

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

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

Класс QStyle в Qt4 имеет API подобный API Qt 3 примерно с тем же набором функций. Изменились лишь заголовки функций и роль отведенная QStyleOption. Например, вот заголовок функции QStyle::drawControl() в Qt 3:

    void drawControl(ControlElement element,
                     QPainter *painter,
                     const QWidget *widget,
                     const QRect &rect,
                     const QColorGroup &colorGroup,
                     SFlags how = Style_Default,
                     const QStyleOption &option = QStyleOption::Default) const;

А вот заголовок той же функции в Qt 4:

    void drawControl(ControlElement element,
                     const QStyleOption *option,
                     QPainter *painter,
                     const QWidget *widget = 0) const;

В Qt 3 часть информации, требуемой для отрисовки графического элемента, передавалась с параметром QStyleOption, а другая часть передавалась вне него, провоцируя сомнительные ситуации. В Qt 4 все помещено в параметр QStyleOption.

[Предыдущая: Модуль Работы с Сетью в Qt 4] [Начало] [Следующая: Поддержка Потоков в Qt 4]


Copyright © 2005 Trolltech Trademarks
Qt 4.1.0
Hosted by uCoz