Синтаксис таблиц стилейТерминология и синтаксические правила таблиц стилей Qt почти идентичны таковым в HTML CSS. Если вы уже знаете CSS, вероятно, вам нужно лишь поверхностно ознакомиться с этим разделом. Правила стилейТаблицы стилей состоят из последовательности правил стилей (style rules). Правило стиля заменяет селектор и декларацию. Селектор определяет виджеты, на которые действует правило; декларация указывает, какие свойства виджета будут установлены. Например: QPushButton { color: red } В вышеприведенном правиле стиля QPushButton - селектор, а { color: red } - декларация. Правило определяет, что QPushButton и его подклассы (например, MyPushButton) должны использовать красный цвет в качестве фона. Таблица стилей Qt, как правило, нечувствительна к регистру (т.е., color, Color, COLOR и cOloR ссылаются на одно и то же свойство). Исключением являются имена классов, имена объектов и имена свойств Qt, являющиеся чувствительными к регистру. Несколько селекторов могут быть заданы для одной и той же декларации, используя запятые (,) для разделения селекторов. Например, правило QPushButton, QLineEdit, QComboBox { color: red } эквивалентно такой последовательности из трех правил: QPushButton { color: red } QLineEdit { color: red } QComboBox { color: red } Декларативная часть правила стиля представляет собой список пар свойство: значение, заключенных в фигурные скобки ({}) и разделенных точкой с запятой. Например: QPushButton { color: red; background-color: white } Чтобы узнать список свойств, предоставляемых виджетами Qt, смотрите раздел Список свойств ниже. Селектор типовДо сих пор все примеры использовали простейший тип селектора - селектор типа (Type Selector). Таблицы стилей Qt поддерживают все селекторы, описанные в CSS2. В таблице ниже обобщены наиболее полезные типы селекторов.
Субэлементы управленияДля оформления сложных виджетов необходимо получить доступ к субэлементам управления виджета, таким как кнопка выпадающего списка (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:
КаскадированиеТаблицы стилей могут быть установлены на приложение 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() распространяется на дочерние виджеты. Виджеты внутри пространств имен C++Селектор типа может быть использован для применения стиля к виджетам заданного типа. Например, class MyPushButton : public QPushButton { // ... } // ... qApp->setStyleSheet("MyPushButton { background: yellow; }"); Таблица стилей Qt Style использует QObject::className() виджета чтобы определить, когда применить селектор типа. Когда пользовательские виджеты находятся внутри пространств имен, QObject::className() вернет <namespace>::<classname>. Это приводит к конфликту с синтаксисом субэлементов управления. Чтобы справиться с этой проблемой при использовании селектора типа для виджетов внутри пространств имен нужно заменить "::" на "--". Например, namespace ns { class MyPushButton : public QPushButton { // ... } } // ... qApp->setStyleSheet("ns--MyPushButton { background: yellow; }"); Настройка свойств QObjectНачиная с версии 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 документации на русский язык... Люди внесшие вклад в перевод: Команда переводчиков |