Spec-Zone.ru › Qt 5.9

Стили и стилизованные виджеты

Стили (классы, наследующие QStyle) выполняют отрисовку от имени виджетов и инкапсулируют вид и ощущения графического интерфейса пользователя. Класс QStyle — это абстрактный базовый класс, который инкапсулирует вид и ощущения графического интерфейса пользователя. Встроенные виджеты Qt используют его для выполнения практически всей отрисовки, обеспечивая, что они выглядят точно так же, как эквивалентные родные виджеты.

Qt поставляется с набором встроенных стилей. Некоторые стили доступны только на определённых платформах (например, стили для Mac и Windows Vista). Пользовательские стили предоставляются в виде плагинов или создаются путём создания экземпляра конкретного класса стиля с помощью QStyleFactory::create() и установки его с помощью QApplication::setStyle().

Настройка стиля

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

Реализация пользовательского стиля

QCommonStyle предоставляет удобную основу для реализации пользовательских стилей. Подход аналогичен использованию QProxyStyle, но вместо него необходимо унаследовать QCommonStyle и переопределить соответствующие виртуальные методы. Реализация полностью пользовательского стиля несколько сложна, поэтому мы предоставляем это обзорное руководство. Мы дадим пошаговое руководство по стилизации отдельных виджетов Qt. Мы рассмотрим виртуальные функции, члены-переменные и перечисления класса QStyle.

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

Для разработки стилизованных виджетов (то есть виджетов, которые соответствуют стилю, в котором они отрисовываются), необходимо отрисовывать их с использованием текущего стиля. В этом документе показано, как виджеты отрисовывают себя и какие возможности предоставляются стилем.

Классы для стилизации виджетов

Эти классы используются для настройки внешнего вида и стиля приложения.

QCursor

Курсор мыши с произвольной формой

QPalette

Содержит группы цветов для каждого состояния виджета

QColor

Цвета, основанные на значениях RGB, HSV или CMYK

QFont

Определяет шрифт, используемый для отрисовки текста

QFontDatabase

Информация о доступных шрифтах в базовой системе окон

QFontInfo

Общая информация о шрифтах

QGraphicsAnchor

Представляет привязку между двумя элементами в QGraphicsAnchorLayout

QGraphicsAnchorLayout

Макет, где можно привязывать виджеты друг к другу в представлении графики

QCommonStyle

Инкапсулирует общий вид и ощущения графического интерфейса пользователя

QStyle

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

QStyleFactory

Создаёт объекты QStyle

QStyleHintReturn

Подсказки стиля, возвращающие больше, чем базовые типы данных

QStyleHintReturnMask

Подсказки стиля, возвращающие QRegion

QStyleHintReturnVariant

Подсказки стиля, возвращающие QVariant

QStyleOption

Хранит параметры, используемые функциями QStyle

QStylePainter

Удобный класс для отрисовки элементов QStyle внутри виджета

Реализация QStyle

API QStyle содержит функции для отрисовки виджетов, статические вспомогательные функции для выполнения общих и сложных задач (например, вычисления положения ползунков ползунковых регуляторов) и функции для выполнения различных вычислений во время отрисовки (например, для виджетов, чтобы вычислить их подсказки размера). Стиль также помогает некоторым виджетам в размещении их содержимого. Кроме того, он создаёт QPalette, который содержит QBrush для отрисовки.

QStyle отрисовывает графические элементы; элемент — это виджет или часть виджета, например, обрамление кнопки, рамка окна или полоса прокрутки. Большинство функций отрисовки теперь принимают четыре аргумента:

  • значение перечисления, определяющее, какой графический элемент отрисовать
  • QStyleOption, определяющий, как и где отрисовать этот элемент
  • QPainter, который должен использоваться для отрисовки элемента
  • QWidget, на котором выполняется отрисовка (необязательно)

Когда виджет просит стиль отрисовать элемент, он предоставляет стилю QStyleOption, который является классом, содержащим информацию, необходимую для отрисовки. Благодаря QStyleOption, можно заставить QStyle отрисовывать виджеты без связывания какого-либо кода для виджета. Это позволяет использовать функции отрисовки QStyle на любом устройстве отрисовки, то есть вы можете отрисовать раскрывающийся список на любом виджете, а не только на QComboBox.

Виджет передаётся в качестве последнего аргумента, в случае если стилю необходимо выполнить специальные эффекты (например, анимированные кнопки по умолчанию в macOS), но это не обязательно.

В ходе этого раздела мы рассмотрим элементы стиля, опции стиля и функции QStyle. Наконец, мы опишем использование палитры.

Элементы в представлениях элементов отрисовываются делегатами в Qt. Заголовки представления элементов по-прежнему отрисовываются стилем. Делегат по умолчанию Qt, QStyledItemDelegate, частично отрисовывает свои элементы с помощью текущего стиля; он отрисовывает индикаторы флажков и вычисляет ограничивающие прямоугольники для элементов, из которых состоит элемент. В этом документе мы описываем только то, как реализовать подкласс QStyle. Если вы хотите добавить поддержку других типов данных, отличных от тех, которые поддерживает QStyledItemDelegate, вам необходимо реализовать пользовательский делегат. Обратите внимание, что делегаты должны устанавливаться программно для каждого отдельного виджета (то есть делегаты по умолчанию не могут предоставляться в виде плагинов).

Элементы стиля

Элемент стиля — это графическая часть графического интерфейса пользователя. Виджет состоит из иерархии (или дерева) элементов стиля. Например, когда стиль получает запрос на отрисовку кнопки (например, от QPushButton), он отрисовывает метку (текст и значок), обрамление кнопки и рамку фокуса. Обрамление кнопки, в свою очередь, состоит из рамки вокруг обрамления и двух других элементов, которые мы рассмотрим позже. Ниже приведён концептуальный пример дерева элементов кнопки. Мы увидим фактическое дерево для QPushButton, когда пройдёмся по отдельным виджетам.

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

Существует три типа элементов: примитивные элементы, элементы управления и сложные элементы управления. Эти элементы определяются перечислениями ComplexControl, ControlElement и PrimitiveElement. Значения каждого перечисления элементов имеют префикс для идентификации их типа: CC_ для сложных элементов, CE_ для элементов управления и PE_ для примитивных элементов. В следующих трёх разделах мы рассмотрим, что определяет различные элементы, и увидим примеры виджетов, которые их используют.

Описание класса QStyle содержит список этих элементов и их роли в стилизации виджетов. Мы увидим, как они используются при стилизации отдельных виджетов.

Примитивные элементы

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

Элементы управления

Элемент управления выполняет действие или отображает информацию пользователю. Примеры элементов управления — это кнопки, флажки и заголовки столбцов в таблицах и деревьях. Элементы управления не обязательно являются полными виджетами, такими как кнопки, но также могут быть частями виджетов, например, вкладки на вкладках и ползунки полос прокрутки. Они отличаются от примитивных элементов тем, что не являются пассивными, а выполняют функцию во взаимодействии с пользователем. Управляющие элементы, состоящие из нескольких элементов, часто используют стиль для вычисления границ элементов. Доступные подэлементы определяются перечислением SubElement. Это перечисление используется только для вычисления границ; подэлементы не являются графическими элементами, которые нужно рисовать, как примитивные, управляющие и сложные элементы.

Сложные элементы управления

Сложные элементы управления содержат подэлементы управления. Сложные элементы ведут себя по-разному в зависимости от того, где пользователь взаимодействует с ними мышкой и какие клавиши нажаты на клавиатуре. Это зависит от того, над каким подэлементом (если таковой имеется) находится курсор мыши или на каком он нажат. Примеры сложных элементов управления — полосы прокрутки и комбинационные поля. С помощью полосы прокрутки вы можете перемещать ползунок мышкой и нажимать кнопки «вверх» и «вниз». Доступные подэлементы определяются перечислением SubControl.

Помимо рисования, стиль должен предоставлять виджетам информацию о том, на каком подэлементе (если таковой имеется) был выполнен щелчок мышью. Например, QScrollBar должен знать, нажал ли пользователь на ползунок, желоб ползунка или на одну из кнопок.

Обратите внимание, что подэлементы не являются теми же элементами управления, что описаны в предыдущем разделе. Вы не можете использовать стиль для рисования подэлемента; стиль будет только вычислять прямоугольник, в котором должен быть нарисован подэлемент. Однако часто сложные элементы используют элементы управления и примитивные элементы для рисования своих подэлементов, что является распространённым подходом в встроенных стилях Qt и Java стиля. Например, Java стиль использует PE_IndicatorCheckBox для рисования флажка в группах (которая является подэлементом CC_GroupBox). Некоторые подэлементы имеют эквивалентный элемент управления, например, ползунок полосы прокрутки (SC_SCrollBarSlider и CE_ScrollBarSlider).

Другие задачи QStyle

Элементы стиля и виджеты, как упоминалось ранее, используют стиль для вычисления прямоугольников подэлементов и подэлементов управления. Пиксельные метрики, которые являются зависящими от стиля размерами в пикселях экрана, также используются для измерений при рисовании. Доступные прямоугольники и пиксельные метрики представлены тремя перечислениями в QStyle: SubElement, SubControl и PixelMetric. Значения перечислений легко идентифицировать, так как они начинаются с SE_, SC_ и PM_.

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

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

Стиль вычисляет отступы между виджетами в макетах. Существует два способа, которыми стиль может обрабатывать эти вычисления. Вы можете установить PM_LayoutHorizontalSpacing и PM_LayoutVerticalSpacing, что является способом, используемым Java-стилем (через QCommonStyle). В качестве альтернативы, вы можете реализовать QStyle::layoutSpacing() и QStyle::layoutSpacingImplementation(), если вам нужен больший контроль над этой частью макета. В этих функциях вы можете вычислить отступы на основе типов элементов управления (QSizePolicy::ControlType) для различных политик размеров (QSizePolicy::Policy) и также опции стиля для рассматриваемого виджета.

Параметры стиля

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

Виджеты могут находиться в ряде различных состояний, которые определяются перечислением State. Некоторые флаги состояний имеют разное значение в зависимости от виджета, но другие являются общими для всех виджетов, такие как State_Disabled. Именно QStyleOption устанавливает общие состояния с помощью QStyleOption::initFrom; остальные состояния устанавливаются отдельными виджетами.

Наиболее заметно, что параметры стиля содержат палитру и прямоугольники элементов управления, которые будут нарисованы. Большинство виджетов имеют специализированные параметры стиля. QPushButton и QCheckBox, например, используют QStyleOptionButton в качестве своего параметра стиля, который содержит текст, значок и размер их значка. Точное содержание всех параметров описывается при рассмотрении отдельных виджетов.

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

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

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

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

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

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

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

class CustomStyle : public QProxyStyle
{
    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) {
        QPolygon 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 & State_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 {
    QProxyStyle::drawPrimitive(element, option, painter, widget);
    }
}

Функции QStyle

Класс QStyle определяет три функции для рисования примитивных, управляющих и сложных элементов: drawPrimitive(), drawControl() и drawComplexControl(). Функции принимают следующие параметры:

  • значение перечисления элемента для рисования.
  • объект QStyleOption, содержащий информацию, необходимую для рисования элемента.
  • объект QPainter для рисования элемента.
  • указатель на QWidget, обычно виджет, на котором отображается элемент.

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

Класс QStyle также предоставляет вспомогательные функции, используемые при рисовании элементов. Функция drawItemText() рисует текст в заданном прямоугольнике, принимая QPalette в качестве параметра. Функция drawItemPixmap() помогает выровнять пиксель в заданном прямоугольнике.

Другие функции QStyle выполняют различные вычисления для функций, выполняющих рисование. Виджеты также используют эти функции для расчёта подсказок размера и ограничивающих прямоугольников, если они сами рисуют несколько элементов стиля.

  • Функция subElementRect() принимает значение перечисления SubElement и вычисляет ограничивающий прямоугольник для подэлемента. Стиль использует эту функцию, чтобы знать, где рисовать разные части элемента. Это делается в основном для повторного использования; если вы создаете новый стиль, вы можете использовать то же расположение подэлементов, что и у суперкласса.
  • Функция subControlRect() используется для вычисления ограничивающих прямоугольников для подконтролей в сложных элементах управления. При реализации нового стиля вы переопределяете subControlRect() и вычисляете прямоугольники, отличающиеся от суперкласса.
  • Функция pixelMetric() возвращает пиксельный параметр, являющийся зависящим от стиля размером в пикселях экрана. Она принимает значение перечисления PixelMetric и возвращает соответствующее измерение. Обратите внимание, что пиксельные параметры не обязательно должны быть статическими измерениями, но могут вычисляться, например, с использованием опции стиля.
  • Функция hitTestComplexControl() возвращает подконтроль, над которым находится указатель мыши в сложном элементе управления. Обычно это просто вопрос использования subControlRect() для получения ограничивающих прямоугольников подконтролей и затем проверки, какой прямоугольник содержит положение курсора.

QStyle также имеет функции polish() и unpolish(). Все виджеты отправляются в функцию polish() перед отображением и в функцию unpolish() при скрытии. Вы можете использовать эти функции для установки атрибутов виджетов или выполнения другой работы, необходимой вашему стилю. Например, если вам нужно узнать, когда курсор мыши находится над виджетом, необходимо установить атрибут виджета WA_Hover. Флаг состояния State_MouseOver затем будет установлен в опциях стиля виджета.

QStyle имеет несколько статических вспомогательных функций, выполняющих некоторые распространённые и сложные задачи. Они могут вычислять положение ползунка ползунка по значению ползунка и преобразовывать прямоугольники и рисовать текст с учётом обратной компоновки; см. документацию класса QStyle для получения дополнительной информации.

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

Палитра

Каждый стиль предоставляет палитру цветов — т.е., QBrush — которая должна использоваться для рисования виджетов. Существует один набор цветов для различных состояний виджетов (QPalette::ColorGroup): активный (виджеты в окне, имеющие фокус клавиатуры), неактивный (виджеты, используемые для других окон) и отключённый (виджеты, которые отключены). Состояния можно найти, запросив флаги состояния State_Active и State_Enabled. Каждый набор содержит определённые цветовые роли, задаваемые перечислением QPalette::ColorRole. Роли описывают ситуации, в которых цвета должны использоваться (например, для рисования фонов виджетов, текста или кнопок).

Как используются цветовые роли, зависит от стиля. Например, если стиль использует градиенты, можно использовать цвет палитры и сделать его темнее или светлее с помощью QColor::darker() и QColor::lighter() для создания градиента. В общем случае, если вам нужен кисть, которая не предоставляется палитрой, следует попытаться вывести её из какой-либо.

QPalette, которая предоставляет палитру, хранит цвета для различных состояний виджетов и цветовых ролей. Палитра для стиля возвращается методом standardPalette(). Стандартная палитра не устанавливается автоматически при установке нового стиля в приложении (QApplication::setStyle()) или виджете (QWidget::setStyle()), поэтому вы должны установить палитру самостоятельно с помощью (QApplication::setPalette()) или (QWidget::setPalette()).

Не рекомендуется жестко кодировать цвета, так как приложения и отдельные виджеты могут устанавливать свою палитру и также использовать палитру своего стиля для рисования. Обратите внимание, что ни один из виджетов Qt не устанавливает свою палитру. Стиль Java жестко кодирует некоторые цвета, но только по решению автора; этого не рекомендуется делать. Конечно, не предполагается, что стиль должен выглядеть хорошо с любой палитрой.

Вопросы реализации

При реализации стилей следует учитывать ряд вопросов. Здесь мы дадим некоторые подсказки и рекомендации по реализации.

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

Рекомендуется, чтобы стили не изменяли предлагаемый размер виджетов с помощью функции QStyle::sizeFromContents(), а позволили реализации QCommonStyle обрабатывать его вместо этого. Если изменения необходимы, следует стараться сохранять их малыми; разработка приложений может оказаться трудной, если макет виджетов значительно отличается в различных стилях.

Стиль Java

Мы реализовали стиль, напоминающий стандартный вид Java (ранее известный как Metal). Мы сделали это, так как это относительно просто реализовать, и мы хотели создать стиль для данного обзорного документа. Чтобы упростить и не слишком усложнить, мы немного упростили стиль, но Qt может совершенно точно скопировать стиль. Однако нет конкретных планов по реализации стиля как части Qt.

В этом разделе мы рассмотрим некоторые вопросы реализации. Наконец, мы увидим полный пример стилизации виджета Java. Мы будем продолжать использовать стиль Java в документе для примеров и изображений виджетов. Сама реализация довольно сложная, и не предполагается, что вы должны её прочитать.

Проектирование и реализация

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

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

Ограничения и различия со стилем Java

Мы не полностью реализовали каждый элемент в стиле Java. Таким образом, мы уменьшили объём и сложность кода. В целом, стиль был задуман как практический пример для данного обзорного документа по стилям, а не как часть самого Qt.

Не у всех виджетов реализованы все состояния. Это относится к общим состояниям, например, State_Disabled. Однако каждое состояние реализовано, по крайней мере, для одного виджета.

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

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

Мы жестко запрограммировали цвета (мы не используем QPalette) для линейных градиентов, которые используются, например, для скосов кнопок, панелей инструментов и флажков. Это связано с тем, что палитра Java не может генерировать эти цвета. В любом случае Java не изменяет эти цвета в зависимости от группы или роли цвета виджета (они не зависят от палитры), поэтому это не представляет проблемы.

Стилизуются виджеты Qt. Некоторые виджеты вообще отсутствуют в Java, например, QToolBox. Другие содержат элементы, которых нет в виджетах Java. Например, виджет дерева — это пример последнего, в котором у Java JTree нет заголовка.

Стиль не обрабатывает обратную компоновку. Мы предполагаем, что направление компоновки слева направо. QCommonStyle обрабатывает виджеты с обратной компоновкой; если бы мы реализовали обратные компоновки, виджеты, которые изменяют положение подэлементов или обрабатывают выравнивание текста в метках сами, потребовали бы обновления.

Стилизация флажков Java

В качестве примера мы рассмотрим стилизацию флажков в стиле Java. Мы опишем весь процесс и напечатаем весь код, как в стиле Java, так и в классах Qt, участвующих в этом. В остальной части этого документа мы не будем рассматривать исходный код отдельных виджетов. Надеюсь, это даст вам представление о том, как искать в коде, если вам нужно проверить конкретные детали реализации; большинство виджетов следуют той же структуре, что и флажки. Мы немного изменили код QCommonStyle, чтобы убрать код, не имеющий непосредственного отношения к стилизации флажков.

Мы начнем с рассмотрения того, как QCheckBox создает свой вариант стиля, который для флажков представляет собой QStyleOptionButton:

    opt.initFrom(q);
        if (down)
        opt.state |= QStyle::State_Sunken;
    if (tristate && noChange)
        opt.state |= QStyle::State_NoChange;
    else
        opt.state |= checked ? QStyle::State_On :
        QStyle::State_Off;
    if (q->testAttribute(Qt::WA_Hover) &&  q->underMouse()) {
        if (hovering)
        opt.state |= QStyle::State_MouseOver;
        else
        opt.state &= ~QStyle::State_MouseOver;
    }
    opt.text = text;
    opt.icon = icon;
    opt.iconSize = q->iconSize();

Сначала мы позволим QStyleOption настроить вариант с информацией, общей для всех виджетов с initFrom(). Мы рассмотрим это в ближайшее время.

Переменная QStyleOption's down имеет значение true, когда пользователь нажимает на поле; это верно для флажка, независимо от того, отмечен ли флажок или нет. Состояние State_NoChange устанавливается, когда у нас есть трехпозиционный флажок, и он частично отмечен. Оно имеет значение State_On, если флажок отмечен, и State_Off, если он не отмечен. State_MouseOver устанавливается, если курсор мыши находится над флажком, и у виджета установлен атрибут Qt::WA_Hover - вы устанавливаете это в QStyle::polish(). Кроме того, вариант стиля также содержит текст, значок и размер значка кнопки.

initFrom() настраивает вариант стиля с атрибутами, общими для всех виджетов. Мы печатаем его реализацию здесь:

    state = QStyle::State_None;
    if (widget->isEnabled())
        state |= QStyle::State_Enabled;
    if (widget->hasFocus())
        state |= QStyle::State_HasFocus;
    if (widget->window()->testAttribute(Qt::WA_KeyboardFocusChange))
        state |= QStyle::State_KeyboardFocusChange;
    if (widget->underMouse())
        state |= QStyle::State_MouseOver;
    if (widget->window()->isActiveWindow())
        state |= QStyle::State_Active;
#if 0 // Used to be included in Qt4 for Q_WS_MAC
    extern bool qt_mac_can_clickThrough(const QWidget *w); //qwidget_mac.cpp
    if (!(state & QStyle::State_Active) && !qt_mac_can_clickThrough(widget))
        state &= ~QStyle::State_Enabled;
#endif
#ifdef QT_KEYPAD_NAVIGATION
    if (widget->hasEditFocus())
        state |= QStyle::State_HasEditFocus;
#endif

    direction = widget->layoutDirection();
    rect = widget->rect();
    palette = widget->palette();
    fontMetrics = widget->fontMetrics();

Флаг State_Enabled устанавливается, когда виджет активен. Когда виджет получает фокус, устанавливается флаг State_HasFocus. Аналогично, флаг State_Active устанавливается, когда виджет является дочерним элементом активного окна. Флаг State_MouseOver будет установлен только в том случае, если для виджета установлен флаг WA_HoverEnabled окна. Обратите внимание, что для включения State_HasEditFocus в Qt должна быть включена навигация с помощью клавиатуры; по умолчанию она не включена.

В дополнение к установке флагов состояния QStyleOption содержит другую информацию о виджете: direction — направление макета, rect — ограничивающая прямоугольник виджета (область, в которой следует рисовать), palette — QPalette, которая должна использоваться для рисования виджета, и fontMetrics — метрики шрифта, используемого виджетом.

Мы даем изображение флажка и соответствующий ему вариант стиля.

Флажок в стиле Java

У приведенного выше флажка в его варианте стиля будут следующие флаги состояния:

Флаг состояния Установлен
State_Sunken Да
State_NoChange Нет
State_On Да
State_Off Нет
State_MouseOver Да
State_Enabled Да
State_HasFocus Да
State_KeyboardFocusChange Нет
State_Active Да

QCheckBox рисует себя в QWidget::paintEvent() с вариантом стиля opt и QStylePainter p. Класс QStylePainter — это вспомогательный класс для рисования элементов стиля. В частности, он оборачивает методы QStyle, используемые для рисования.

QCheckBox рисует себя следующим образом:

    QStylePainter p(this);
    QStyleOptionButton opt = d->getStyleOption();
    p.drawControl(QStyle::CE_CheckBox, opt);

QCommonStyle обрабатывает элемент CE_CheckBox. QCheckBox имеет два подэлемента: SE_CheckBoxIndicator (указатель отмеченного состояния) и SE_CheckBoxContents (содержимое, используемое для метки флажка). QCommonStyle также реализует ограничивающие прямоугольники этих подэлементов. Далее мы рассмотрим код QCommonStyle:

    QStyleOptionButton subopt = *btn;
    subopt.rect = subElementRect(SE_CheckBoxIndicator, btn, widget);
    drawPrimitive(PE_IndicatorCheckBox, &subopt, p, widget);
    subopt.rect = subElementRect(SE_CheckBoxContents, btn, widget);
    drawControl(CE_CheckBoxLabel, &subopt, p, widget);

    if (btn->state & State_HasFocus) {
        QStyleOptionFocusRect fropt;
        fropt.QStyleOption::operator=(*btn);
        fropt.rect = subElementRect(SE_CheckBoxFocusRect, btn, widget);
        drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
    }

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

Стиль Java рисует CE_CheckBoxIndicator, а QCommonStyle обрабатывает CE_CheckboxLabel. Мы рассмотрим каждую реализацию и начнем с CE_CheckBoxLabel:

    const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt);
    uint alignment = visualAlignment(btn->direction, Qt::AlignLeft | Qt::AlignVCenter);

    if (!styleHint(SH_UnderlineShortcut, btn, widget))
        alignment |= Qt::TextHideMnemonic;
    QPixmap pix;
    QRect textRect = btn->rect;
    if (!btn->icon.isNull()) {
        pix = btn->icon.pixmap(btn->iconSize, btn->state & State_Enabled ? QIcon::Normal : QIcon::Disabled);
        drawItemPixmap(p, btn->rect, alignment, pix);
        if (btn->direction == Qt::RightToLeft)
            textRect.setRight(textRect.right() - btn->iconSize.width() - 4);
        else
            textRect.setLeft(textRect.left() + btn->iconSize.width() + 4);
    }
    if (!btn->text.isEmpty()){
        drawItemText(p, textRect, alignment | Qt::TextShowMnemonic,
            btn->palette, btn->state & State_Enabled, btn->text, QPalette::WindowText);
    }

visualAlignment() корректирует выравнивание текста в соответствии с направлением макета. Затем, если существует значок, мы рисуем его и корректируем оставшееся пространство для текста. drawItemText() рисует текст, учитывая выравнивание, направление макета и метку. Он также использует палитру для рисования текста в нужном цвете.

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

Теперь мы рассмотрим реализацию Java для CE_CheckBoxIndicator в drawControl():

        case PE_IndicatorCheckBox: {
            painter->save();
            drawButtonBackground(option, painter, true);

            if (option->state & State_Enabled &&
                option->state & State_MouseOver &&
                !(option->state & State_Sunken)) {
                painter->setPen(option->palette.color(QPalette::Button));
                QRect rect = option->rect.adjusted(1, 1, -2, -2);
                painter->drawRect(rect);
                rect = rect.adjusted(1, 1, -1, -1);
                painter->drawRect(rect);
            }

            if (option->state & State_On) {
                QImage image(":/images/checkboxchecked.png");
                painter->drawImage(option->rect.topLeft(), image);
            }
            painter->restore();
            break;

Сначала мы сохраняем состояние рисовальщика. Это не всегда необходимо, но в данном случае QCommonStyle нуждается в рисовальщике в том же состоянии, что и при вызове PE_IndicatorCheckBox (разумеется, мы также можем установить состояние с помощью вызовов функций). Затем мы используем drawButtonBackground(), чтобы нарисовать фон указателя флажка. Это вспомогательная функция, которая рисует фон и рамку кнопок и флажков. Мы рассмотрим эту функцию ниже. Затем мы проверяем, находится ли мышь над флажком. Если да, то мы рисуем рамку, которая есть у флажков Java, когда флажок не нажат, а мышь находится над ним. Вы можете заметить, что Java не обрабатывает трехпозиционные флажки, поэтому мы не реализовали эту функциональность.

Здесь мы используем PNG-изображение для нашего указателя. Мы также можем проверить, не является ли виджет отключенным. Тогда нам пришлось бы использовать другое изображение с указателем в отключенном цвете.

void JavaStyle::drawButtonBackground(const QStyleOption *option,
                                     QPainter *painter, bool isCheckbox) const
{
    QBrush buttonBrush = option->palette.button();
    bool sunken = option->state & State_Sunken;
    bool disabled = !(option->state & State_Enabled);
    bool on = option->state & State_On;

    if (!sunken && !disabled && (!on || isCheckbox))
        buttonBrush = gradientBrush(option->rect);

        painter->fillRect(option->rect, buttonBrush);

        QRect rect = option->rect.adjusted(0, 0, -1, -1);

        if (disabled)
            painter->setPen(option->palette.color(QPalette::Disabled,
                                                  QPalette::WindowText));
        else
            painter->setPen(option->palette.color(QPalette::Mid));

        painter->drawRect(rect);

        if (sunken && !disabled) {
            drawSunkenButtonShadow(painter, rect,
                   option->palette.color(QPalette::Mid),
                   option->direction == Qt::RightToLeft);
    }
}

Мы рассмотрели, как стилизуются флажки в стиле Java, начиная с запроса на отрисовку виджета и заканчивая завершением рисования стилем. Чтобы подробно узнать, как рисуется каждый виджет, необходимо пройти по коду шаг за шагом, как это сделано здесь. Однако, как правило, достаточно знать, какие элементы стиля рисуют виджеты. Виджет создает вариант стиля и вызывает стиль один или несколько раз, чтобы нарисовать элементы стиля, из которых он состоит. Обычно также достаточно знать, в каких состояниях может находиться виджет, и другое содержимое варианта стиля, т. е. то, что мы перечислили в следующем разделе.

Обзор виджетов

В этом разделе мы рассмотрим, как стилизуются большинство виджетов Qt. Надеюсь, это сэкономит ваше время и усилия при разработке собственных стилей и виджетов. Здесь вы не найдете информации, недоступной в других местах (т.е. путем изучения исходного кода или описаний классов, связанных со стилем).

В основном мы будем использовать виджеты в стиле Java в качестве примеров. Стиль Java не рисует каждый элемент в дереве элементов. Это связано с тем, что для этого виджета они не видны в стиле Java. Мы все равно гарантируем, что все элементы реализованы так, чтобы соответствовать стилю Java, так как пользовательские виджеты могут их потребовать (хотя это не исключает передачи реализации QCommonStyle).

Для каждого виджета предоставляется следующее:

  • Таблица членов (переменных и т.д.) его варианта стиля.
  • Таблица флагов состояния (QStyle::StateFlag), которые могут быть установлены на виджете и когда устанавливаются состояния.
  • Дерево элементов (см. раздел Элементы стиля).
  • Изображение виджета, на котором элементы выделены.

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

Наш подход к стилизации сосредоточен на рисовании виджетов. Вычисления прямоугольников подэлементов, подэлементов управления и пиксельных метрик, используемых во время рисования, указаны только как содержимое в деревьях элементов. Обратите внимание, что есть прямоугольники и пиксельные метрики, используемые только виджетами. Это оставляет эти вычисления необработанными в обзоре. Например, функции subControlRect() и sizeFromContents() часто вызывают subElementRect() для расчета своих ограничительных прямоугольников. Мы могли бы нарисовать деревья и для этого. Однако способ выполнения этих вычислений полностью зависит от отдельных стилей, и они не должны следовать какой-либо определенной структуре (Qt не навязывает определенной структуры). Тем не менее, вы должны убедиться, что используете соответствующие пиксельные метрики. Для сокращения объема документа мы, следовательно, решили не включать деревья и не описывать вычисления, выполняемые стилем Java (или любым другим).

Вы можете запутаться в том, как следует использовать различные пиксельные метрики, прямоугольники подэлементов и прямоугольники подэлементов управления при изучении деревьев. Если у вас есть сомнения после прочтения описаний перечисления QStyle, мы рекомендуем вам изучить реализацию QCommonStyle.

Некоторые из ограничительных прямоугольников, которые мы выделяем на изображениях виджетов, совпадают. Причины этого заключаются в том, что некоторые элементы рисуют фон, а другие — рамки и метки. В случае сомнений проверьте описание каждого элемента в QStyle. Кроме того, некоторые элементы предназначены для макета, т.е. для определения места рисования, других элементов.

Общие свойства виджетов

Общие состояния и переменные применимы ко всем виджетам. Они устанавливаются с помощью QStyleOption::initFrom(). Не все элементы используют эту функцию; виджеты создают параметры стиля, а для некоторых элементов информация из initFrom() не требуется.

Следующая таблица содержит общие состояния:

Состояние Время установки состояния
State_Enabled Устанавливается, если виджет не отключен (см. QWidget::setEnabled())
State_Focus Устанавливается, если виджет имеет фокус (см. QWidget::hasFocus())
State_KeyobordFocusChange Устанавливается при изменении фокуса пользователем с помощью клавиатуры (см. Qt::WA_KeyboardFocusChange)
State_MouseOver Устанавливается, если курсор мыши находится над виджетом
State_Active Устанавливается, если виджет является дочерним элементом активного окна.
State_HasEditFocus Устанавливается, если виджет имеет фокус редактирования

Другие общие члены для виджетов:

Член Содержание
rect Прямоугольник, определяющий область элемента для отрисовки. Он устанавливается в прямоугольник области виджета (QWidget::rect()).
direction Направление макета; значение из перечисления Qt::LayoutDirection.
palette QPalette для отрисовки элемента. Устанавливается в палитру виджета (QWidget::palette()).
fontMetrics QFontMetrics для отрисовки текста на виджете.

В сложных параметрах стиля (классах, наследующих QStyleOptionComplex) для сложных элементов стиля используются две переменные: subControls и activeSubControls. Обе переменные представляют собой результат побитового ИЛИ операций над значениями перечисления QStyle::SubControl. Они указывают, из каких подэлементов состоит сложный элемент управления и какие из этих элементов в настоящее время активны.

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

Справочник по виджетам

Без дальнейших задержек мы представляем обзор виджетов; каждый виджет имеет свой подраздел.

Кнопки

Структура стиля для кнопок показана ниже. Последовательное обход дерева сверху вниз дает последовательность элементов, которые должны быть нарисованы.

<img alt="Структура стиля для кнопок" src="data:image/png;base64,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</p>

Расположение кнопок, относительно границ элементов, меняется в зависимости от стиля. Это затрудняет демонстрацию концептуальных изображений. Кроме того, элементы могут иметь одинаковые границы (или даже должны иметь одинаковые границы); например, PE_PushButtonBevel, используется в QCommonStyle для рисования элементов, содержащихся в нём: PE_FrameDefaultButton, PE_FrameButtonBevel, и PE_PanelButtonCommand, все из которых имеют общие границы в общем стиле. PE_PushButtonBevel также отвечает за отображение индикатора меню (QCommonStyle рисует PE_IndicatorArrowDown).

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

Стиль Java, как и все другие стили, реализованные в Qt, не использует PE_FrameButtonBevel. Обычно кнопка с PE_DefaultFrame корректирует прямоугольник PE_PanelButtonCommand на PM_ButtonDefaultIndicator. CE_PushButtonLabel находится путем корректировки прямоугольника на PM_DefaultFrameWidth.

Сейчас мы рассмотрим параметр стиля для кнопок - QStyleOptionButton. Ниже представлена таблица состояний, которые QPushButton может установить в параметре стиля:

Состояние Устанавливается, когда
State_Sunken Кнопка нажата или показано меню
State_On Кнопка выбрана
State_Raised Кнопка не плоская и не нажата

Другие члены QStyleOptionButton:

Член Содержание
features Флаги перечисления QStyleOptionButton::ButtonFeatures, описывающие различные свойства кнопки (см. перечисление)
icon Иконка кнопки (QIcon), если имеется
iconSize Размер иконки (QSize)
text Строка (QString) с текстом кнопки

Кнопки выбора и радиокнопки

Структуры для радиокнопок и кнопок выбора идентичны. Мы покажем структуру, используя элемент QCheckBox и имена пиксельных метрик:

QStyleOptionButton используется в качестве параметра стиля для кнопок выбора и радиокнопок. Сначала приведём таблицу состояний, которые могут быть установлены в параметре:

Состояние Устанавливается, когда
State_sunken Квадрат нажат
State_NoChange Квадрат частично выбран (для кнопок выбора с тремя состояниями)
State_On Квадрат выбран
State_Off Квадрат не выбран

См. Кнопки для таблицы других членов в классе QStyleOptionButton.

Вкладки

В Qt, QTabBar использует стиль для отрисовки своих вкладок. Вкладки существуют либо в QTabWidget, который содержит QTabBar, либо как отдельная панель. Если панель не является частью виджета вкладок, она рисует собственное основание.

QTabBar размещает вкладки, поэтому стиль не контролирует расположение вкладок. Однако, при размещении своих вкладок, панель запрашивает у стиля PM_TabBarTabHSpace и PM_TabBarTabVSpace, что представляет собой дополнительную ширину и высоту по отношению к минимальному размеру метки вкладки панели (иконка и текст). Стиль также может дополнительно влиять на размер вкладки перед её размещением, поскольку панель запрашивает CT_TabBarTab. Границы панели определяются виджетом вкладок, когда она является частью виджета (по-прежнему учитывая CT_TabBarTab).

Панель вкладок отвечает за рисование кнопок, которые появляются на панели вкладок, когда все вкладки не помещаются. Их расположение не контролируется стилем, но кнопки являются QToolButton и поэтому рисуются стилем.

Вот структура стиля для QTabWidget и QTabBar:

Точечные линии указывают на то, что QTabWidget содержит панель вкладок, но не рисует её сам. QTabBar рисует только свою базовую линию, когда не является частью виджета вкладок, и он сохраняет две кнопки инструментов, которые прокручивают панель, когда все вкладки не помещаются; см. Кнопки инструментов для их структуры элементов. Также обратите внимание, что поскольку кнопки являются дочерними элементами панели вкладок, они отрисовываются после панели. Границы элементов вкладок перекрывают базу на PM_TabBarBaseOverlap.

Вот виджет вкладок в стиле Java:

В стиле Java, форма вкладки и метка имеют ту же область, что и CE_TabBarTab. Обратите внимание, что вкладки перекрываются рамкой виджета вкладок. Основание панели вкладок (если нарисована) — это область, где вкладки и рамка перекрываются.

Вариант стиля для вкладок (QStyleOptionTab) содержит необходимую информацию для отрисовки вкладок. Параметр содержит положение вкладки на панели вкладок, положение выделенной вкладки, форму вкладки, текст, значок и размер значка.

Так как вкладки в стиле Java не перекрываются, мы также предоставляем изображение виджета вкладок в общем стиле. Обратите внимание, что если вы хотите, чтобы вкладки перекрывались горизонтально, вы делаете это при отрисовке вкладок в CE_TabBarTabShape; области вкладок не будут изменены панелью вкладок. Вкладки отрисовываются слева направо в форме панели вкладок «север», сверху вниз в форме панели вкладок «восток» и т. д. Выделенная вкладка рисуется последней, чтобы её легко было нарисовать поверх других (если она должна быть больше).

Следующая таблица содержит состояния, которые может установить панель вкладок на своих вкладках:

Состояние Состояние установлено, когда
State_Sunken Вкладка нажата мышью.
State_Selected Если это текущая вкладка.
State_HasFocus Панель вкладок имеет фокус и вкладка выделена.

Обратите внимание, что отдельные вкладки могут быть отключены, даже если панель вкладок не отключена. Вкладка будет активной, если активна панель вкладок.

Ниже приведена таблица членов QStyleOptionTab:

Элемент Содержание
cornerWidgets Флаги перечисления CornerWidget, указывающие, есть ли и какие виджеты углов у полосы вкладок.
icon QIcon вкладки.
iconSize QSize значка.
position Значение перечисления TabPosition, указывающее положение вкладки на полосе относительно других вкладок.
row Содержит номер строки, в которой находится вкладка.
selectedPosition Значение перечисления SelectedPosition, указывающее, расположена ли выбранная вкладка рядом или это сама вкладка.
shape Значение перечисления QTabBar::Shape, указывающее, имеют ли вкладки закругленные или треугольные углы, а также ориентацию вкладки.
text Текст вкладки.

Фрейм для виджетов вкладок использует QStyleOptionTabWidgetFrame в качестве опции стиля. Мы перечисляем его члены здесь. Кроме общих флагов, он не имеет установленных состояний.

Элемент Содержание
leftCornerWidgetSize QSize виджета левого угла (если таковой имеется).
rightCornerWidgetSize QSize виджета правого угла (если таковой имеется).
lineWidth Содержит ширину линии для отрисовки панели.
midLineWith Это значение в настоящее время всегда равно 0.
shape Форма вкладок на полосе вкладок.
tabBarSize QSize полосы вкладок.

Скроллбары

Вот структура стиля для скроллбаров:

QScrollBar просто создаёт его опцию стиля, а затем рисует CC_ScrollBar. Некоторые стили рисуют фон добавочной страницы и подстраницы с помощью PE_PanelButtonBevel, а также используют стрелки-индикаторы для рисования стрелок в индикаторах следующей и предыдущей строки; мы не включили их в дерево, так как их использование зависит от конкретного стиля. Стилевое PM_MaximumDragDistance — это максимальное расстояние в пикселях, на которое мышь может сместиться от границ скроллбара и всё ещё перемещать ползунок.

Вот изображение скроллбара в стиле Java:

Вы можете заметить, что полоса прокрутки немного отличается от полосы прокрутки Java, так как она имеет два указателя строк. Мы сделали это, чтобы показать, что у вас может быть две отдельные ограничивающие прямоугольные области для одного подэлемента. Полоса прокрутки является примером виджета, который полностью реализован в стиле Java - QCommonStyle не участвует в отрисовке.

Давайте рассмотрим различные состояния, которые может установить полоса прокрутки в опции стиля:

Состояние Устанавливается, когда
State_Horizontal Полоса прокрутки горизонтальная.

Опция стиля QScrollBar является QStyleOptionSlider. Ее члены перечислены в следующей таблице. Эта опция используется для всех QAbstractSlider; здесь мы описываем члены, относящиеся к полосам прокрутки.

Член Содержание
maximum Максимальное значение полосы прокрутки.
minimum Минимальное значение полосы прокрутки.
notchTarget Количество пикселей между насечками.
orientation Значение перечисления Qt::Orientation, указывающее, является ли полоса прокрутки вертикальной или горизонтальной.
pageStep Число, на которое нужно увеличить или уменьшить значение ползунка при нажатии на кнопки прокрутки (относительно размера ползунка и диапазона значений).
singleStep Число, на которое нужно увеличить или уменьшить значение ползунка при нажатии на кнопки перемещения на один шаг.
sliderValue Значение ползунка.
sliderPosition Позиция ползунка. Это то же самое, что sliderValue если полоса прокрутки имеет QAbstractSlider::tracking. Если нет, полоса прокрутки не обновляет свое значение до отпускания ползунка.
upsideDown Содержит направление, в котором полоса прокрутки увеличивает свое значение. Используется вместо QStyleOption::direction для всех абстрактных ползунков.

Ползунки

При расчете размера подсказки ползунка запрашиваются PM_SliderThickness и PM_SliderLength. Как и в случае с полосами прокрутки, QSlider позволяет пользователю перемещать ползунок только если курсор находится в пределах PM_MaximumDragDistance от границ ползунка. При отрисовке он создает опцию стиля и вызывает drawComplexControl() с CC_Slider.

Мы также показываем изображение ползунка в стиле Java. Мы отображаем ограничивающие прямоугольные области подэлементов, так как вся отрисовка выполняется в CC_Slider.

QSlider использует QStyleOptionSlider, как и все QAbstractSlider. Мы представляем таблицу с членами, которые влияют на QSlider:

Элемент Описание
maximum Максимальное значение ползунка.
minimum Минимальное значение ползунка.
notchTarget Количество пикселей между каждой риской.
orientation Значение перечисления Qt::Orientation, указывающее, вертикальный или горизонтальный ползунок.
pageStep Число, на которое увеличивается или уменьшается значение ползунка при нажатии на шаги разворота страницы.
singleStep Число, на которое увеличивается или уменьшается значение ползунка при нажатии на шаги (или шаги по строке).
sliderValue Значение ползунка.
sliderPosition Положение ползунка, заданное как значение ползунка. Оно будет равно sliderValue если ползунок отслеживается; в противном случае, значение ползунка не изменится, пока рукоятка не будет отпущена мышкой.
upsideDown Этот член используется вместо QStyleOption::direction для всех абстрактных ползунков.

Обратите внимание, что ползунок не использует направление для обратной компоновки; он использует upsideDown.

Поле ввода со списком

Когда QSpinBox рисует себя, он создаёт QStyleOptionSpinBox и просит стиль нарисовать CC_SpinBox. Поле редактирования — это поле ввода строки, являющееся дочерним элементом поля ввода со списком. Размеры поля вычисляются стилем с помощью SC_SpinBoxEditField.

Ниже приведён древовидный вид стиля для полей ввода со списком. Не требуется, чтобы стиль использовал примитив панели кнопок для отрисовки фонов индикаторов. Ниже дерева представлено изображение, показывающее подэлементы в QSpinBox в стиле Java.

Вариант стиля QStyleOptionSpinBox, который является вариантом стиля для полей ввода со списком. Он может устанавливать следующие состояния для поля ввода со списком:

Состояние Устанавливается когда
State_Sunken Устанавливается, если одна из подконтролей CC_SpinUp или CC_SpinDown нажата мышкой.

Остальные члены в вариантах стиля поля ввода со списком:

Свойство Функция
frame Булево значение, равное true, если для поля ввода со списком нужно нарисовать рамку.
buttonSymbols Значение перечисления ButtonSymbols, определяющее символ на кнопках вверх/вниз.
stepEnabled Значение перечисления StepEnabled, указывающее, какие из кнопок поля ввода со списком нажаты.

Панель заголовка

Комплексное управление панелью заголовка, CC_TitleBar, используется для отрисовки панелей заголовков внутренних окон в QMdiArea. Обычно она состоит из заголовка окна и кнопок «Закрыть», «Свернуть», «Меню системы», «Развернуть». Некоторые стили также предоставляют кнопки для затемнения окна и кнопку для вызова контекстной справки.

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

На изображении над строкой заголовка в стиле Java мы показываем ограничивающие прямоугольники подэлементов, поддерживаемых стилем Java (все они отрисовываются стандартными пиксельными изображениями). Обычно фоны кнопок рисуются с помощью PE_PanelButtonTool, но это не обязательно.

Вариант стиля для строк заголовков — QStyleOptionTitleBar. Его члены:

class="generic" width="90%"> class="odd" valign="top"> class="even" valign="top"> class="odd" valign="top"> class="even" valign="top">
ЧленСодержимое
iconИконка строки заголовка.
textТекст для метки строки заголовка.
windowFlagsФлаги перечисления Qt::WindowFlag. Флаги окна, используемые QMdiArea для управления окном.
titleBarStateЭто QWidget::windowState() окна, содержащего строку заголовка.

Комбо-бокс

QComboBox использует стиль для отрисовки кнопки и метки нередактируемых полей с помощью CC_ComboBox и CE_ComboBoxLabel.

Список, который появляется при нажатии на комбо-бокс, отрисовывается делегатом делегат, который мы не рассматриваем в этом обзоре. Однако вы можете использовать стиль для управления размером и положением списка с помощью подэлемента SC_ComboBoxListBoxPopup. Стиль также определяет, где должно находиться поле редактирования для редактируемых полей с помощью SC_ComboBoxEditField; само поле — это QLineEdit, являющийся дочерним элементом комбо-бокса.

Мы показываем изображение над комбинированным полем в стиле Java, в котором мы обвели его подэлементы и прямоугольники подэлементов:

Комбинированные поля Java не используют прямоугольник фокуса; он изменяет свой цвет фона, когда имеет фокус. Поле SC_ComboBoxEdit используется как QComboBox для вычисления размера поля редактирования, так и для стиля, используемого для вычисления размера метки комбинированного поля.

Стилевой параметр для комбинированных полей — QStyleOptionComboBox. Он может устанавливать следующие состояния:

Состояние Устанавливается, когда
State_Selected Поле не редактируется и имеет фокус.
State_Sunken SC_ComboBoxArrow активен.
State_on Контейнер (список) поля виден.

Другие члены стилевых параметров:

Член Содержимое
currentIcon Значок текущего (выбранного) элемента комбинированного поля.
currentText Текст текущего элемента в поле.
editable Указывает, редактируется ли комбинированное поле.
frame Указывает, есть ли у комбинированного поля рамка.
iconSize Размер значка текущего элемента.
popupRect Прямоугольник области видимости выпадающего списка комбинированного поля.

Групповые поля

При вычислении размера подсказки QGroupBox извлекает три пиксельных значения из стиля: PM_IndicatorWidth, PM_CheckBoxLabelSpacing, и PM_IndicatorHeight. QGroupBox имеет следующий древовидный элемент стиля:

Qt не накладывает ограничений на то, как рисуется флажок; в стиле Java он рисуется с помощью CE_IndicatorCheckBox. См. Флажки и радиокнопки для полного дерева.

Мы также даем изображение виджета с нарисованными подключаемыми элементами и прямоугольниками подключаемых элементов:

Вариант стиля для групповых элементов — QStyleOptionGroupBox. Можно установить следующие состояния:

Состояние Устанавливается когда
State_On Флажок отмечен.
State_Sunken Флажок нажат.
State_Off Флажок не отмечен (или флажка нет).

Остальные члены QStyleOptionGroupBox:

Член Описание
features Флаги перечисления QStyleOptionFrame::FrameFeatures, описывающие рамку группового элемента.
lineWidth Ширина линии панели. Всегда равна 1.
text Текст группового элемента.
textAlignment Выравнивание заголовка группового элемента.
textColor Цвет текста QColor.

Разделители

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

Для своего стиля разделитель использует базовый класс QStyleOption. Он может устанавливать следующие флаги состояния:

Состояние Устанавливается когда
State_Horizontal Устанавливается, если это горизонтальный разделитель.

QSplitter не использует initFrom() для настройки своего варианта; он сам устанавливает флаги State_MouseOver и State_Disabled.

Полоса прогресса

Элемент CE_ProgressBar используется QProgressBar, и это единственный элемент, используемый этим виджетом. Начнём со структуры стиля:

Вот полоса прогресса в общем стиле (прямоугольники Java-стиля равны):

Вариант стиля для QProgressBar — QStyleOptionProgressBar. Полоска не устанавливает никаких флагов состояния, но другие члены опции:

Элемент Описание
minimum Минимальное значение полоски.
maximum Максимальное значение полоски.
progress Текущее значение полоски.
textAlignment Выравнивание текста в метке.
textVisible Отображение метки.
text Текст метки.
orientation Полоски могут быть вертикальными или горизонтальными.
invertedAppearance Инвертированный прогресс (например, справа налево в горизонтальной полоске).
bottomToTop Булево значение, которое, если true, поворачивает метку вертикальных полосок на 90 градусов.

Кнопки инструментов

Кнопки инструментов существуют как независимо, так и в составе панелей инструментов. Отрисовка в обоих случаях одинаковая. Элемент стиля QToolButton рисует только один элемент стиля: CC_ToolButton.

Ниже приведён древовидный вид структуры стиля виджета:

Обратите внимание, что PE_FrameButtonTool и PE_IndicatorArrowDown включены в дерево, как нарисовано в стиле Java, но их можно безопасно опустить, если вы этого хотите. Структура также может быть другой. QCommonStyle, например, рисует как PE_IndicatorButtonDropDown и PE_IndicatorArrowDown в CE_ToolButton.

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

Вот таблица состояний для кнопок инструментов:

Состояние Устанавливается когда
State_AutoRise Кнопка инструмента имеет свойство autoRise.
State_Raised Кнопка не утоплена (т. е., не отмечена или нажата мышкой).
State_Sunken Кнопка нажата.
State_On Кнопка может быть отмечена и отмечена.

QStyleOptionToolButton также содержит следующие члены:

Элемент Описание
arrowType Значение перечисления Qt::ArrowType, содержащее направление стрелки кнопок (если стрелка используется вместо значка).
features Флаги перечисления QStyleOptionToolButton::ButtonFeature, описывающие, содержит ли кнопка стрелку, меню и/или имеет задержку всплытия.
font QFont шрифта метки кнопок.
icon QIcon значка инструментальной кнопки.
iconSize Размер значка значка кнопки.
pos Позиция кнопки, заданная с помощью QWidget::pos()
text Текст кнопки.
toolButtonStyle Значение перечисления Qt::ToolButtonStyle, определяющее, отображается ли значок, текст или оба.

Панели инструментов

Панели инструментов являются частью фреймворка главного окна и взаимодействуют с QMainWindow, к которому они относятся, при построении его опций стиля. Главное окно имеет 4 области, в которых могут размещаться панели инструментов. Они размещаются рядом со сторонами окна (т. е. север, юг, восток и запад). В каждой области может быть более одной строки панелей инструментов; строка состоит из панелей инструментов с одинаковой ориентацией (вертикальной или горизонтальной), расположенных рядом друг с другом.

Панели инструментов в Qt состоят из трёх элементов: CE_ToolBar, PE_IndicatorToolBarHandle, и PE_IndicatorToolBarSeparator. Это QMainWindowLayout, который рассчитывает ограничивающие прямоугольники (т. е. позицию и размер панелей инструментов и их содержимого. Главное окно также использует sizeHint() элементов в панелях инструментов при расчёте размера панелей.

Вот древовидная структура элементов для QToolBar:

Штриховые линии указывают, что QToolBar хранит экземпляр QToolBarLayout, а QToolBarSeparators хранятся в QToolBarLayout. Когда панель инструментов плавающая (т. е. имеет собственное окно), отображается элемент PE_FrameMenu, иначе QToolBar отображает CE_ToolBar.

Вот изображение панели инструментов в стиле Java:

QToolBarSaparator использует QStyleOption для его стиля. Он устанавливает флаг State_Horizontal, если панель инструментов, в которой он находится, горизонтальная. Помимо этого, они используют initFrom().

Стиль для QToolBar — QStyleOptionToolBar. Единственный установленный флаг состояния (кроме общих флагов) — State_Horizontal, если панель горизонтальная (то есть в области панели инструментов «север» или «юг»). Переменные-члены стиля:

Член Содержание
features Указывает, можно ли перемещать панель, в значении ToolBarFeature, которое может быть Movable или None.
lineWidth Ширина рамки панели инструментов.
midLineWidth Эта переменная в данный момент не используется и всегда равна 0.
positionOfLine Положение линии панели инструментов в области панели инструментов, к которой она относится.
positionWithinLine Положение панели инструментов на линии панели инструментов.
toolBarArea Область панели инструментов, в которой находится панель инструментов.

Меню

Меню в Qt реализованы в QMenu. QMenu хранит список действий, которые отображаются как пункты меню. Когда QMenu получает события рисования, он рассчитывает размер каждого пункта меню и рисует их индивидуально с помощью CE_MenuItem. У пунктов меню нет отдельного элемента для метки (содержимого), поэтому все рисование выполняется в CE_MenuItem. Меню также рисует рамку меню с помощью PE_FrameMenu. Также рисуются CE_MenuScroller, если стиль поддерживает прокрутку. CE_MenuTearOff рисуется, если меню слишком велико для своей области.

В дереве структуры стиля мы также включаем QMenu, поскольку он также выполняет работу по стилизации. Границы пунктов меню вычисляются для размера подсказки меню и при отображении или изменении размера меню.

Элементы CE_MenuScroller и CE_MenuTearOff обрабатываются QCommonStyle и не отображаются, если меню слишком большое для экрана. PE_FrameMenu отображается только для всплывающих меню.

QMenu вычисляет прямоугольники, основанные на своих действиях, и вызывает CE_MenuItem и CE_MenuScroller, если стиль это поддерживает.

Также обычно используется PE_IndicatorCheckBox (вместо PE_IndicatorMenuCheckMark) и PE_IndicatorRadioButton для рисования изменяемых элементов меню; мы не включили их в дерево стилей, поскольку это необязательно и зависит от конкретного стиля.

Опция стиля для элементов меню — QStyleOptionMenuItem. В следующих таблицах описываются флаги состояния и другие члены.

Состояние Устанавливается когда
State_Selected Указатель мыши над действием, и действие не является разделителем.
State_Sunken Кнопка мыши нажата на элемент меню.
State_DownArrow Устанавливается, если элемент меню — прокрутка меню, и она прокручивает меню вниз.
Элемент Описание
checkType Значение перечисления CheckType, которое может быть NotCheckable, Exclusive или NonExclusive.
checked Логическое значение true, если элемент меню отмечен.
font QFont для отображения текста элемента меню.
icon QIcon элемента меню.
maxIconWidth Максимальная ширина иконки.
menuHasChecableItem Логическое значение true, если хотя бы один элемент меню допускает отметку.
menuItemType Тип элемента меню. Значение перечисления MenuItemType.
menuRect Ограничительная прямоугольная область для QMenu, в которой находится элемент меню.
tabWidth Расстояние между текстом элемента меню и сочетанием клавиш.
text Текст элемента меню.

Настройка стиля для CE_MenuTearOff и CE_MenuScroller также использует QStyleOptionMenuItem; они только устанавливают переменную menuRect, помимо общих настроек со QStyleOption's initFrom().

Панель меню

QMenuBar использует стиль для отрисовки каждого элемента панели меню и пустого места. Сами раскрывающиеся меню являются QMenu (см. Меню). Структура элементов стиля для панели меню имеет следующий вид:

Панель и пустое место отрисовываются после элементов меню. QPainter, который отправляет QMenuBar стилю, имеет обрезающиеся прямоугольные области элементов (т.е., область обрезки), поэтому вам не нужно беспокоиться об отрисовке поверх элементов. Пиксельные метрики в QMenuBar используются при расчете прямоугольных областей элементов панели меню.

QStyleOptionMenuItem используется для элементов панели меню. Члены, которые используются QMenuBar, описаны в следующей таблице:

Элемент Описание
menuRect Прямоугольная область всей панели меню, к которой относится элемент.
text Текст элемента.
icon Иконка элемента меню (редко используется для отрисовки стилями).

QStyleOptionMenuItem также используется для отрисовки CE_EmptyMenuBarArea.

QStyleOptionFrame используется для отрисовки рамки панели. lineWidth установлено в PM_MenuBarPanelWidth. midLineWidth всегда установлено в 0.

Заголовки представления элементов

Стиль отвечает за отрисовку заголовков представлений элементов Qt. Представления элементов сохраняют размеры отдельных разделов. Также обратите внимание, что делегаты могут использовать стиль для рисования декораций и рамок вокруг элементов. Например, QItemDelegate рисует PE_FrameFocusRect и PE_IndicatorViewItemCheck.

Вот QTableWidget, отображающий ограничивающие прямоугольники Java-заголовка:

Заголовок QHeaderView использует CT_HeaderSection, PM_HeaderMargin и PM_HeaderGripMargin для расчета размера и проверки попадания. PM_HeaderMarkSize в настоящее время Qt не использует. QTableView рисует кнопку в верхнем левом углу (т.е., в области пересечения вертикального и горизонтального заголовков) как %%%CODE_BLOCK_184%%.

Параметр стиля для заголовков — QStyleOptionHeader. Вид рисует один раздел заголовка за раз, поэтому данные относятся к отображаемому разделу. Его содержимое:

Элемент Содержание
icon Значок заголовка (для раздела, который рисуется).
iconAlignment Выравнивание (Qt::Alignment) значка в заголовке.
orientation Значение Qt::Orientation, определяющее, является ли заголовок горизонтальным заголовком над представлением или вертикальным заголовком слева.
position Значение QStyleOptionHeader::SectionPosition, задающее положение раздела заголовка относительно других разделов.
section Содержит раздел, который рисуется.
selectedPosition Значение QStyleOptionHeader::SelectedPosition, задающее положение выделенного раздела относительно раздела, который рисуется.
sortIndicator Значение QStyleOptionHeader::SortIndicator, описывающее направление, в котором должен быть нарисован индикатор сортировки раздела.
text Текст текущего раздела.
textAlignment Qt::Alignment текста внутри раздела заголовка.

Индикаторы ветвей дерева

Индикаторы ветвей в представлении дерева рисуются стилем с помощью PE_IndicatorBranch. Мы рассматриваем индикаторы как индикаторы, описывающие отношения узлов в дереве. Для рисования этих элементов в стиль отправляется обобщённый QStyleOption. Различные типы ветвей описываются состояниями. Поскольку нет специального параметра стиля, мы просто приводим таблицу состояний:

Состояние Устанавливается при
State_Sibling Узел в дереве имеет соседний узел (то есть существует другой узел в том же столбце).
State_Item Этот индикатор ветви имеет элемент.
State_Children Ветвь имеет потомков (то есть новая подветвь может быть открыта в ветви).
State_Open У индикатора ветви открыта подветвь.

Представление дерева (и виджет дерева) использует стиль для рисования ветвей (узлов) дерева.

QStyleOption используется как стиль для PE_IndicatorBranch с установленным флагами состояния в зависимости от типа ветви.

Поскольку для индикаторов ветвей нет структуры дерева, мы показываем только изображение дерева в стиле Java. Каждое состояние отмечено на изображении прямоугольником определенного цвета (то есть прямоугольники не являются ограничивающими прямоугольниками). На изображении представлены все возможные комбинации состояний, которые необходимо учитывать.

<img alt="" src="data:image/png;base64,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

Панели инструментов

PM_SmallIconSize для размера значений.

QToolBox — это контейнер, который хранит коллекцию виджетов. У него есть одна вкладка для каждого виджета, и он отображает только один из них за раз. Панель инструментов размещает отображаемые компоненты (кнопки панели инструментов и выбранный виджет) в QVBoxLayout. Дерево стилей для панелей инструментов выглядит так:

Мы показываем изображение панели инструментов в стиле Plastique:

Мы показываем маркер размера в правом нижнем углу QMainWindow.

Все элементы имеют одинаковые прямоугольники ограничивающей рамки в стиле Plastique, а также в других встроенных стилях Qt.

Вариант стиля для панелей инструментов — это QStyleOptionToolBox. Он содержит текст и значок содержимого панели инструментов. Единственное состояние, устанавливаемое QToolBox, — это State_Sunken, которое устанавливается, когда пользователь нажимает вкладку вниз мышью. Остальные члены QStyleOptionToolBox:

Член Содержание
icon Значок на вкладке панели инструментов.
text Текст на вкладке панели инструментов.

Маркер размера

Маркер размера вычисляет свой размер с помощью CT_SizeGrip. Пиксельная метрика PM_SizeGripSize в настоящее время не используется Qt. Дерево элементов для изображения в стиле Plastique QSizeGrip выглядит так:

Мы показываем маркер размера в правом нижнем углу QMainWindow.

Вариант стиля размера захвата, QStyleOptionSizeGrip, имеет один член помимо общих членов из QStyleOption:

Член Содержание
corner Значение Qt::Corner, описывающее угол окна (или эквивалента), в котором расположен захват.

Резиновая полоска

Дерево стилей QRubberBand состоит из двух узлов.

Мы представляем изображение окна стиля Java, перемещаемого в QMdiArea с резиновой полоской:

Вариант стиля для резиновых полосок — QStyleOptionRubberBand. Его члены:

Член Содержание
opaque Булево значение, которое равно true если резиновая полоска должна быть нарисована в непрозрачном стиле (т. е. цветом).
shape Значение перечисления QRubberBand::Shape, которое содержит форму полосы (прямоугольник или линия).

Виджеты док-станций

Когда виджет док-станции компонует своё содержимое, он запрашивает у стиля следующие метрики в пикселях: PM_DockWidgetSeparatorExtent, PM_DockWidgetTitleBarButtonMargin, PM_DockWidgetFrameWidth, и PM_DockWidgetTitleMargin. Он также вычисляет ограничивающие прямоугольники кнопок плавающего и закрытия с помощью SE_DockWidgetCloseButton и SE_DockWidgetFloatButton.

Пунктирные линии указывают, что отправитель сохраняет экземпляры получателя стрелки (то есть это не элемент стиля для рисования). Виджет док только рисует PE_frameDockWidget при откреплении от основного окна (то есть это окно верхнего уровня). Если он прикреплен, он рисует индикатор-маркер изменения размера док-виджета. Мы показываем док-виджет в состоянии прикрепления и плавающего состояния в стиле пластик:

<img alt="" src="data:image/png;base64,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

Опция стиля — QStyleOptionDockWidget:

Член Содержание
closeable Логическое значение, указывающее, можно ли закрыть окно виджета.
floatable Логическое значение, указывающее, может ли окно виджета плавать (т.е., отделяться от основного окна).
movable Логическое значение, указывающее, можно ли перемещать окно (т.е., переместить в другие области виджета).
title Текст заголовка окна виджета.

Для кнопок используется QStyleOptionButton (см. Кнопки инструментов для описания содержимого). Ручка изменения размера виджета имеет обычную QStyleOption.

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.9/style-reference.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API