[Предыдущая: Таблицы стилей Qt] [Содержание] [Следующая: Интеграция с Qt Designer] Синтаксис таблиц стилей
|
Селектор | Пример | Пояснение |
---|---|---|
Универсальный селектор | * | Соответствует всем виджетам. |
Селектор типа | QPushButton | Соответствует экземплярам класса QPushButton и его подклассов. |
Селектор свойства | QPushButton[flat="false"] | Соответствуют экземплярам класса QPushButton, которые не являются плоскими (flat). Можно использовать этот селектор для проверки свойства Qt, которое поддерживает QVariant::toString() (за подробностями обращайтесь к документации функции toString()). Кроме того, для имени класса поддерживается специальное свойство class. Этот селектор можно также использовать для проверки динамических свойств. За дополнительной информацией по настройке с использованием динамических свойств обратитесь к статье Настройка с использованием динамических свойств. Вместо = вы можете также использовать ~= для проверки содержит ли свойство Qt типа QStringList заданную строку QString. Предупреждение: Если значение свойства Qt изменится после установки таблицы стилей, то может потребоваться принудительно перерассчитать таблицу стилей. Одним из способов добиться этого - сбросить таблицу стилей и установить ее снова. |
Селектора класса | .QPushButton | Соответствует экземплярам класса QPushButton, но не его подклассов. Эквивалентно выражению *[class~="QPushButton"]. |
Селектор идентификатора (ID) | QPushButton#okButton | Соответствует всем экземплярам класса QPushButton, чье имя объекта равно okButton. |
Селектор потомков | QDialog QPushButton | Соответствует всем экземплярам класса QPushButton, которые являются наследниками класса QDialog (дочерними, внучатыми и т.д.). |
Селектор дочерних элементов | QDialog > QPushButton | Соответствует всем экземплярам класса QPushButton, являющихся непосредственными потомками QDialog. |
Для оформления сложных виджетов необходимо получить доступ к субэлементам управления виджета, таким как кнопка выпадающего списка (drop-down button) в QComboBox или кнопки увеличения и уменьшения значения в окошке счетчика QSpinBox. Селекторы могут содержать субэлементы управления, что делает возможным ограничить использование правила для отдельных субэлементов управления виджета. Например:
QComboBox::drop-down { image: url(dropdown.png) }
Вышеприведенное правило применяет стиль к кнопке выпадающего списка во всех объектах QComboBox. Хотя синтаксис с двойным двоеточием (::) напоминает псевдоэлементы из CSS3, субэлементы управления Qt концептуально отличаются от них и обладают другой семантикой каскадирования.
Субэлементы управления всегда располагаются относительно другого элемента - ссылочного элемента (reference element). Этим ссылочным элементом может быть виджет или другой субэлемент управления. Например, кнопка выпадающего списка ::drop-down QComboBox'а по умолчанию расположена в верхнем правом углу прямоугольника заполнения QComboBox'а. Кнопка выпадающего списка ::drop-down по умолчанию расположена в центре прямоугольника содержимого субэлемента управления выпадающего списка ::drop-down. Чтобы узнать, какие субэлементы управления можно использовать для применения стиля к виджету и их расположение по умолчанию, смотрите Список виджетов, допускающих применение стиля ниже.
Используемый прямоугольник основы можно изменить используя свойство subcontrol-origin. Например, если мы хотим поместить выпадающий список в прямоугольник полей QComboBox'а вместо используемого по умолчанию прямоугольника заполнения, можно указать:
QComboBox { margin-right: 20px; } QComboBox::drop-down { subcontrol-origin: margin; }
Выравнивание выпадающего списка внутри прямоугольника полей можно изменить с помощью свойства subcontrol-position.
Свойства width и height могут быть использованы для управления размерами субэлемента управления. Обратите внимание на то, что установка свойства image неявным образом устанавливает размеры субэлемента управления.
Схема относительного позиционирования (position : relative), позволяет расположить субэлемент управления со сдвигом относительно первоначальной позиции. Например, когда нажата кнопка выпадающего списка QComboBox'а, нам может понравиться сдвиг стрелки внутри чтобы передать эффект "нажатия". Чтобы этого добиться мы можем указать:
QComboBox::down-arrow { image: url(down_arrow.png); } QComboBox::down-arrow:pressed { position: relative; top: 1px; left: 1px; }
Схема абсолютного позиционирования (position : absolute), позволяет изменять расположение и размеры субэлемента управления с помощью ссылочного элемента.
Однажды расположенные они рассматриваются как виджеты и к ним могут быть применяться стили используя модель "коробки".
Чтобы узнать список поддерживаемых субэлементов управления смотрите Список субэлементов управления ниже, и практический пример в Настройке субэлемента управления индикатора меню QPushButton'а.
Замечание: В случае сложных виджетов, таких как QComboBox и QScrollBar, если одно свойство или субэлемент управления настраивается, то и все остальные свойства или субэлементы управления также должны настраиваться.
Селекторы могут содержать в себе псевдо-состояния, которые указывают что ограничение применения правила основано на состоянии виджета. Псевдо-состояния указываются в конце селектора, разделенные двоеточием (:). Например, следующее правило применяется когда мышь располагается над QPushButton:
QPushButton:hover { color: white }
Псевдо-состояния могут быть инвертированы с помощью оператора восклицательный знак. Например, следующее правило применяется когда мышь не располагается над QRadioButton:
QRadioButton:!hover { color: red }
Псевдо-состояния могут измениться, в таких случаях подразумевается логическое И. Например, следующее правило применяется когда мышь располагается над отмеченным QCheckBox:
QCheckBox:hover:checked { color: white }
Инвертированные псевдо-состояния могут применяться в цепочках псевдо-состояний. Например, следующее правило применяется когда мышь располагается над QPushButton и она не нажата:
QPushButton:hover:!pressed { color: blue; }
Если необходимо, логическое ИЛИ может быть выражено используя оператор запятая:
QCheckBox:hover, QCheckBox:checked { color: white }
Псевдо-состояния могут применяться в комбинации с субэлементами управления. Например:
QComboBox::drop-down:hover { image: url(dropdown_bright.png) }
Чтобы узнать список псевдо-состояний, предоставляемых виджетами Qt, смотрите раздел Список псевдо-состояний ниже.
Конфликты появляются когда несколько правил стиля определяют для одних и тех же свойств разные значения. Рассмотрим следующую таблицу стилей:
QPushButton#okButton { color: gray } QPushButton { color: red }
Оба правила соответствуют экземплярам QPushButton вызывающих okButton и имеется конфликт в свойстве color. Для разрешения этого конфликта мы должны учитывать специфику селекторов. В вышеприведенном примере правило QPushButton#okButton считается более специфичным, чем QPushButton, поскольку оно (обычно) ссылается на единственный объект, а не на все экземпляры класса.
Аналогично, селекторы с псевдо-состояниями более специфичны, чем селекторы без псевдо-состояний. Таким образом, следующая таблица стилей определяет, что у QPushButton должен быть текст белого цвета когда мышь располагается над ней, в остальных случаях - текст красного цвета:
QPushButton:hover { color: white } QPushButton { color: red }
Вот более хитрая таблица стилей:
QPushButton:hover { color: white } QPushButton:enabled { color: red }
Здесь оба селектора имеют одинаковую специфику, поэтому если мышь располагается над кнопкой пока она включена (enabled), второе правило получает приоритет. Если мы хотим чтобы текст в этом случае был белого цвет, то мы можем реорганизовать правила, например, так:
QPushButton:enabled { color: red } QPushButton:hover { color: white }
В качестве альтернативы, мы можем сделать первое правило более специфичным:
QPushButton:hover:enabled { color: white } QPushButton:enabled { color: red }
Похожая проблема возникает при объединении с селекторами типа. Рассмотрим следующий пример:
QPushButton { color: red } QAbstractButton { color: gray }
Оба правила применяются к экземплярам QPushButton (так как QPushButton унаследован от QAbstractButton) и возникает конфликт для свойства color. Поскольку QPushButton унаследован от QAbstractButton, может быть привлекательным предположить, что QPushButton более специфичен чем QAbstractButton. Однако для вычислений с таблицами стилей, все селекторы типа обладают одинаковой спецификой, а правило, идущее последним, получает приоритет. Другими словами, color устанавливается в значение gray для всех объектов QAbstractButton, включая объекты QPushButton. Если мы действительно хотим чтобы объекты QPushButton имели красный цвет, то мы всегда можем реорганизовать правила.
При определении специфики правила таблицы стилей Qt следуют спецификации CSS2:
Специфика селектора вычисляется следующим образом:
- подсчитывается количество атрибутов идентификаторов в селекторе (= a)
- в селекторе подсчитывается количество остальных атрибутов и псевдо-классов (= b)
- в селекторе подсчитывается количество имен элементов (= c)
- пренебрегаем псевдо-элементами [т.е., субэлементами управления].
Тройка связанных чисел a-b-c (в системе счисления с наибольшей базой) дают специфику.
Несколько примеров:
* {} /* a=0 b=0 c=0 -> специфика = 0 */ LI {} /* a=0 b=0 c=1 -> специфика = 1 */ UL LI {} /* a=0 b=0 c=2 -> специфика = 2 */ UL OL+LI {} /* a=0 b=0 c=3 -> специфика = 3 */ H1 + *[REL=up]{} /* a=0 b=1 c=1 -> специфика = 11 */ UL OL LI.red {} /* a=0 b=1 c=3 -> специфика = 13 */ LI.red.level {} /* a=0 b=2 c=1 -> специфика = 21 */ #x34y {} /* a=1 b=0 c=0 -> специфика = 100 */
Таблицы стилей могут быть установлены на приложение QApplication, на родительские и на дочерние виджеты. Эффективная таблица стилей произвольно выбранных виджетов получается путем объединения таблиц стилей, установленных на предков виджета (родительские, предков родителей и т.д.), так же как и любые таблицы стилей установленные на QApplication.
При возникновении конфликтов собственная таблица стилей виджета всегда имеет приоритет перед унаследованной таблицей стилей, независимо от специфики несовместимых правил. Более того, таблица стилей родителя имеет приоритет перед таблицей стилей предка родителя и т.д.
Одним из результатов этого является то, что установка стиля на виджет автоматически дает ему приоритет перед другими правилами, заданными в таблицах стилей предков виджета или в таблице стилей QApplication. Рассмотрим следующий пример. Во-первых, установим таблицу стилей на QApplication:
qApp->setStyleSheet("QPushButton { color: white }");
Далее, установим таблицу стилей на объект QPushButton:
myPushButton->setStyleSheet("* { color: blue }");
Таблица стилей на QPushButton заставляет QPushButton (и любой дочерний виджет) иметь синий текст, вопреки более специфичному набору правил, предоставляемому таблицей стилей приложения.
Результат будет таким же, как если бы мы написали
myPushButton->setStyleSheet("color: blue");
за исключением того, что если у QPushButton имеются потомки (что маловероятно), таблица стилей на них действовать не будет.
Каскадирование таблицы стилей - сложная тема. За подробным описанием обратитесь к Спецификации CSS2. Имейте ввиду, что в настоящее время в Qt не реализовано !important.
В классической CSS, когда шрифт и цвет элемента не установлен явно, они автоматически наследуются от родителя. При использовании таблиц стилей Qt виджет не наследует автоматически настройки шрифта и цветов от родительского виджета.
Например, рассмотрим QPushButton внутри QGroupBox:
qApp->setStyleSheet("QGroupBox { color: red; } ");
У QPushButton цвет явно не установлен. Следовательно, вместо унаследованного цвета своего родителя QGroupBox, она получит системный цвет. Если мы хотим установить цвет для QGroupBox и его потомков, мы можем написать:
qApp->setStyleSheet("QGroupBox, QGroupBox * { color: red; }");
Однако, установка и распространение (propagate) шрифта используя QWidget::setFont() и QWidget::setPalette() распространяется на дочерние виджеты.
Селектор типа может быть использован для применения стиля к виджетам заданного типа. Например,
class MyPushButton : public QPushButton { // ... } // ... qApp->setStyleSheet("MyPushButton { background: yellow; }");
Таблица стилей Qt Style использует QObject::className() виджета чтобы определить, когда применить селектор типа. Когда пользовательские виджеты находятся внутри пространств имен, QObject::className() вернет <namespace>::<classname>. Это приводит к конфликту с синтаксисом субэлементов управления. Чтобы справиться с этой проблемой при использовании селектора типа для виджетов внутри пространств имен нужно заменить "::" на "--". Например,
namespace ns { class MyPushButton : public QPushButton { // ... } } // ... qApp->setSytleSheet("ns--MyPushButton { background: yellow; }");
Начиная с версии 4.3 любой проектируемый макрос Q_PROPERTY может быть установлен используя синтаксис qproperty-<имя свойства>.
Например,
MyLabel { qproperty-pixmap: url(pixmap.png); } MyGroupBox { qproperty-titleColor: rgb(100, 200, 100); } QPushButton { qproperty-iconSize: 20px 20px; }
Если свойство обращается к перечислению, объявленному с помощью Q_ENUMS, вы должны обращаться к ее константам по имени, т.е., не по их численному значению.
[Предыдущая: Таблицы стилей Qt] [Содержание] [Следующая: Интеграция с Qt Designer]
Авторские права © 2010 Nokia Corporation и/или её дочерние компании | Торговые марки | Qt 4.6.4 |
Попытка перевода Qt документации. Если есть желание присоединиться, или если есть замечания или пожелания, то заходите на форум: Перевод Qt документации на русский язык... Люди внесшие вклад в перевод: Команда переводчиков |