Настройка Qt Quick Controls 2
Qt Quick Controls 2 состоит из иерархии (дерева) элементов. Для предоставления пользовательского внешнего вида и ощущения можно заменить стандартную реализацию QML каждого элемента на пользовательскую.
Настройка элемента управления
Иногда требуется создать уникальный вид для определенной части пользовательского интерфейса и использовать стандартный стиль для всех остальных элементов. Возможно, вы довольны используемым стилем, но у определенной кнопки есть особое значение.
Первый способ создания такой кнопки — просто определить её на месте, где она требуется. Например, возможно, вас не устраивает стиль кнопки по умолчанию с прямоугольными углами. Чтобы сделать их закруглёнными, можно переопределить элемент background и установить свойство radius прямоугольника:
import QtQuick 2.6
import QtQuick.Controls 2.1
ApplicationWindow {
width: 400
height: 400
visible: true
Button {
id: button
text: "A Special Button"
background: Rectangle {
implicitWidth: 100
implicitHeight: 40
color: button.down ? "#d6d6d6" : "#f6f6f6"
border.color: "#26282a"
border.width: 1
radius: 4
}
}
} Второй способ создания кнопки хорош, если вы планируете использовать вашу закруглённую кнопку в нескольких местах. Он подразумевает перемещение кода в отдельный файл QML в вашем проекте.
Для этого подхода скопируем код фона из стандартного стиля Button.qml. Этот файл можно найти по следующему пути в вашей установке Qt:
$QTDIR/qml/QtQuick/Controls.2/Button.qml
После этого просто добавим следующую строку:
radius: 4
Чтобы избежать путаницы с элементами управления в самом модуле, назовём файл MyButton.qml. Для использования элемента управления в вашем приложении ссылайтесь на него по имени файла:
import QtQuick.Controls 2.1
ApplicationWindow {
MyButton {
text: qsTr("A Special Button")
}
} Третий способ создания кнопки немного более структурирован как по расположению файла в файловой системе, так и по способу его использования в QML. Сначала скопируйте существующий файл, как описано выше, но на этот раз поместите его в подпапку в вашем проекте, например, controls. Чтобы использовать элемент управления, сначала импортируйте папку в пространство имён:
import QtQuick.Controls 2.1
import "controls" as MyControls
ApplicationWindow {
MyControls.Button {
text: qsTr("A Special Button")
}
} Теперь у вас есть пространство имён MyControls, и вы можете называть элементы управления по их реальным аналогам в модуле Qt Quick Controls 2. Вы можете повторить этот процесс для любого элемента управления, который хотите добавить.
Дополнительное преимущество этих трёх методов состоит в том, что не нужно реализовывать шаблон с нуля.
Создание пользовательского стиля
Существует несколько способов создания собственных стилей. Ниже мы объясним различные подходы.
Определение стиля
В Qt Quick Controls 2 стиль — это в сущности набор взаимозаменяемых файлов QML в одном каталоге. Для того чтобы стиль был используемым, необходимо выполнить три условия:
- Должен существовать хотя бы один файл QML, имя которого соответствует элементу управления (например,
Button.qml) - Каждый файл QML должен содержать соответствующий тип из импорта QtQuick.Templates в качестве корневого элемента. Например, Button.qml должен содержать шаблон Button в качестве корневого элемента.
Если вместо этого мы использовали соответствующий тип из импорта QtQuick.Controls, как делали в предыдущем разделе, это не сработает: элемент управления, который мы определяем, будет пытаться вывести себя из себя.
- Файлы должны находиться в каталоге в файловой системе или в системе ресурсов.
Например, это все допустимые пути к стилю:
./myapp -style /home/absolute/path/to/my/style./myapp -style :/mystyle./myapp -style relative/path/to/my/style./myapp -style MyStyle
Третий и четвёртый пути будут искать в списке путей импорта движка QML. Это то же самое, что происходит, когда вы передаёте
Materialв качестве стиля, например.
По умолчанию система стилизации использует стиль по умолчанию в качестве резервного для элементов управления, которые не реализованы. Чтобы настроить или расширить любой другой встроенный стиль, можно указать другой стиль по умолчанию с помощью QQuickStyle.
Это означает, что вы можете реализовать любое количество элементов управления для вашего пользовательского стиля и разместить их практически где угодно. Это также позволяет пользователям создавать свои собственные стили для вашего приложения.
Предварительный просмотр пользовательских стилей в Qt Quick Designer
Используя описанный выше подход, можно предварительно просмотреть пользовательский стиль в Qt Quick Designer. Для этого убедитесь, что в проекте есть файл qtquickcontrols2.conf и что в нём существует следующая запись:
[Controls] Style=MyStyle
Дополнительную информацию см. в примере Flat Style.
Расширения стиля на C++
Иногда для расширения пользовательского стиля может потребоваться C++. Существует два способа экспонировать такие типы в QML:
- Если стиль, использующий тип, — единственный используемый стиль в приложении, достаточно зарегистрировать его в движке QML с помощью qmlRegisterType():
qmlRegisterType<ACoolCppItem>("MyApp", 1, 0, "ACoolItem");Дополнительную информацию см. в разделе Использование данных C++ из QML.
- Если стиль, использующий тип, — один из многих стилей, используемых приложением, может быть лучше зарегистрировать его только при необходимости. Это момент, когда имеет смысл реализовать собственный QML плагин.
Использование плагина в качестве части стиля не сильно отличается от использования набора файлов QML. Единственное различие заключается в том, что плагин и его
qmldirфайл должны находиться в той же директории, что и файлы QML.
Присоединённые свойства
Для стиля часто существуют определённые свойства или атрибуты, которые применяются ко всем элементам управления. Присоединённые свойства — отличный способ расширить элемент в QML, не изменяя существующий C++ этого элемента. Например, в стилях Material и Universal существует присоединённое свойство theme, которое контролирует, будут ли элемент и его потомки отображаться в светлой или тёмной теме.
В качестве примера добавим присоединённое свойство, которое контролирует высоту. Наш стиль будет иллюстрировать высоту с тенью; чем выше высота, тем больше тень.
Первый шаг — создать новое приложение Qt Quick Controls 2 в Qt Creator. После этого добавим тип C++, который хранит высоту. Поскольку тип будет использоваться для каждого элемента управления, поддерживаемого нашим стилем, и поскольку мы можем захотеть добавить другие присоединённые свойства позже, назовём его MyStyle. Вот MyStyle.h:
#ifndef MYSTYLE_H
#define MYSTYLE_H
#include <QObject>
#include <QtQml>
class MyStyle : public QObject
{
Q_OBJECT
Q_PROPERTY(int elevation READ elevation WRITE setElevation NOTIFY elevationChanged)
public:
explicit MyStyle(QObject *parent = nullptr);
static MyStyle *qmlAttachedProperties(QObject *object);
int elevation() const;
void setElevation(int elevation);
signals:
void elevationChanged();
private:
int m_elevation;
};
QML_DECLARE_TYPEINFO(MyStyle, QML_HAS_ATTACHED_PROPERTIES)
#endif // MYSTYLE_H MyStyle.cpp:
#include "mystyle.h"
MyStyle::MyStyle(QObject *parent) :
QObject(parent),
m_elevation(0)
{
}
MyStyle *MyStyle::qmlAttachedProperties(QObject *object)
{
return new MyStyle(object);
}
int MyStyle::elevation() const
{
return m_elevation;
}
void MyStyle::setElevation(int elevation)
{
if (elevation == m_elevation)
return;
m_elevation = elevation;
emit elevationChanged();
} Тип MyStyle особый в том смысле, что он не должен создаваться, а вместо этого используется для своих присоединённых свойств. По этой причине мы регистрируем его следующим образом в main.cpp:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "mystyle.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
qmlRegisterUncreatableType<MyStyle>("MyStyle", 1, 0, "MyStyle", "MyStyle is an attached property");
QQmlApplicationEngine engine;
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
return app.exec();
} Затем скопируем Button.qml из стиля по умолчанию в $QTDIR/qml/QtQuick/Controls.2/ в новую папку myproject в директории нашего проекта. Добавьте скопированный Button.qml в qml.qrc, который является файлом ресурсов, содержащим наши файлы QML.
Далее добавим тень в делегат background кнопки:
// ...
import QtGraphicalEffects 1.0
import MyStyle 1.0
// ...
background: Rectangle {
// ...
layer.enabled: control.enabled && control.MyStyle.elevation > 0
layer.effect: DropShadow {
verticalOffset: 1
color: control.visualFocus ? "#330066ff" : "#aaaaaa"
samples: control.MyStyle.elevation
spread: 0.5
}
} Обратите внимание, что:
- Мы не используем тень, когда высота
0 - Меняем цвет тени в зависимости от того, имеет ли кнопка фокус
- Делаем размер тени зависимым от высоты
Чтобы попробовать присоединённое свойство, создадим Row с двумя кнопками в main.qml:
import QtQuick 2.6
import QtQuick.Controls 2.1
import MyStyle 1.0
ApplicationWindow {
id: window
width: 400
height: 400
visible: true
Row {
spacing: 20
anchors.centerIn: parent
Button {
text: "Button 1"
}
Button {
text: "Button 2"
MyStyle.elevation: 10
}
}
} Одна кнопка без высоты, а другая с высотой 10.
С этим мы можем запустить наш пример. Чтобы указать приложению использовать наш новый стиль, мы передаём -style :/mystyle в качестве аргумента приложения, но есть многие способы указать используемый стиль.
Конечный результат:
Обратите внимание, что утверждение import MyStyle 1.0 необходимо только потому, что мы используем присоединённое свойство, принадлежащее MyStyle. Обе кнопки будут использовать наш пользовательский стиль, даже если мы удалим импорт.
Справочник по настройке
Следующие фрагменты кода представляют примеры, где элементы управления стандартного стиля были настраивались с использованием того же подхода, что и в разделе Настройка элемента управления. Код можно использовать в качестве отправной точки для реализации пользовательского вида и ощущения.
Настройка ApplicationWindow
ApplicationWindow состоит из одного визуального элемента: background. Также можно настроить элементы modal и modeless.
import QtQuick 2.7
import QtQuick.Controls 2.0
ApplicationWindow {
visible: true
background: Rectangle {
gradient: Gradient {
GradientStop { position: 0; color: "#ffffff" }
GradientStop { position: 1; color: "#c1bbf9" }
}
}
overlay.modal: Rectangle {
color: "#8f28282a"
}
overlay.modeless: Rectangle {
color: "#2f28282a"
}
} Настройка BusyIndicator
BusyIndicator состоит из двух визуальных элементов: background и contentItem.
import QtQuick 2.6
import QtQuick.Controls 2.1
BusyIndicator {
id: control
contentItem: Item {
implicitWidth: 64
implicitHeight: 64
Item {
id: item
x: parent.width / 2 - 32
y: parent.height / 2 - 32
width: 64
height: 64
opacity: control.running ? 1 : 0
Behavior on opacity {
OpacityAnimator {
duration: 250
}
}
RotationAnimator {
target: item
running: control.visible && control.running
from: 0
to: 360
loops: Animation.Infinite
duration: 1250
}
Repeater {
id: repeater
model: 6
Rectangle {
x: item.width / 2 - width / 2
y: item.height / 2 - height / 2
implicitWidth: 10
implicitHeight: 10
radius: 5
color: "#21be2b"
transform: [
Translate {
y: -Math.min(item.width, item.height) * 0.5 + 5
},
Rotation {
angle: index / repeater.count * 360
origin.x: 5
origin.y: 5
}
]
}
}
}
}
} Настройка Button
Button состоит из двух визуальных элементов: background и content item.
import QtQuick 2.6
import QtQuick.Controls 2.1
Button {
id: control
text: qsTr("Button")
contentItem: Text {
text: control.text
font: control.font
opacity: enabled ? 1.0 : 0.3
color: control.down ? "#17a81a" : "#21be2b"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
background: Rectangle {
implicitWidth: 100
implicitHeight: 40
opacity: enabled ? 1 : 0.3
border.color: control.down ? "#17a81a" : "#21be2b"
border.width: 1
radius: 2
}
} Настройка CheckBox
CheckBox состоит из трёх визуальных элементов: background, contentItem и indicator.
import QtQuick 2.6
import QtQuick.Controls 2.1
CheckBox {
id: control
text: qsTr("CheckBox")
checked: true
indicator: Rectangle {
implicitWidth: 26
implicitHeight: 26
x: control.leftPadding
y: parent.height / 2 - height / 2
radius: 3
border.color: control.down ? "#17a81a" : "#21be2b"
Rectangle {
width: 14
height: 14
x: 6
y: 6
radius: 2
color: control.down ? "#17a81a" : "#21be2b"
visible: control.checked
}
}
contentItem: Text {
text: control.text
font: control.font
opacity: enabled ? 1.0 : 0.3
color: control.down ? "#17a81a" : "#21be2b"
verticalAlignment: Text.AlignVCenter
leftPadding: control.indicator.width + control.spacing
}
} Настройка CheckDelegate
CheckDelegate состоит из трёх визуальных элементов: background, contentItem и indicator.
import QtQuick 2.6
import QtQuick.Controls 2.1
CheckDelegate {
id: control
text: qsTr("CheckDelegate")
checked: true
contentItem: Text {
rightPadding: control.indicator.width + control.spacing
text: control.text
font: control.font
opacity: enabled ? 1.0 : 0.3
color: control.down ? "#17a81a" : "#21be2b"
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
}
indicator: Rectangle {
implicitWidth: 26
implicitHeight: 26
x: control.width - width - control.rightPadding
y: control.topPadding + control.availableHeight / 2 - height / 2
radius: 3
color: "transparent"
border.color: control.down ? "#17a81a" : "#21be2b"
Rectangle {
width: 14
height: 14
x: 6
y: 6
radius: 2
color: control.down ? "#17a81a" : "#21be2b"
visible: control.checked
}
}
background: Rectangle {
implicitWidth: 100
implicitHeight: 40
visible: control.down || control.highlighted
color: control.down ? "#bdbebf" : "#eeeeee"
}
} Настройка ComboBox
ComboBox состоит из фонового элемента, элемента содержимого, сплит-меню, индикатора и элемента делегата.
import QtQuick 2.6
import QtQuick.Controls 2.1
ComboBox {
id: control
model: ["First", "Second", "Third"]
delegate: ItemDelegate {
width: control.width
contentItem: Text {
text: modelData
color: "#21be2b"
font: control.font
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
}
highlighted: control.highlightedIndex === index
}
indicator: Canvas {
id: canvas
x: control.width - width - control.rightPadding
y: control.topPadding + (control.availableHeight - height) / 2
width: 12
height: 8
contextType: "2d"
Connections {
target: control
onPressedChanged: canvas.requestPaint()
}
onPaint: {
context.reset();
context.moveTo(0, 0);
context.lineTo(width, 0);
context.lineTo(width / 2, height);
context.closePath();
context.fillStyle = control.pressed ? "#17a81a" : "#21be2b";
context.fill();
}
}
contentItem: Text {
leftPadding: 0
rightPadding: control.indicator.width + control.spacing
text: control.displayText
font: control.font
color: control.pressed ? "#17a81a" : "#21be2b"
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
background: Rectangle {
implicitWidth: 120
implicitHeight: 40
border.color: control.pressed ? "#17a81a" : "#21be2b"
border.width: control.visualFocus ? 2 : 1
radius: 2
}
popup: Popup {
y: control.height - 1
width: control.width
implicitHeight: contentItem.implicitHeight
padding: 1
contentItem: ListView {
clip: true
implicitHeight: contentHeight
model: control.popup.visible ? control.delegateModel : null
currentIndex: control.highlightedIndex
ScrollIndicator.vertical: ScrollIndicator { }
}
background: Rectangle {
border.color: "#21be2b"
radius: 2
}
}
} Настройка DelayButton
DelayButton состоит из двух визуальных элементов: фонового элемента и элемента содержимого.
import QtQuick 2.6
import QtQuick.Controls 2.2
DelayButton {
id: control
checked: true
text: qsTr("Delay\nButton")
contentItem: Text {
text: control.text
font: control.font
opacity: enabled ? 1.0 : 0.3
color: "white"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
background: Rectangle {
implicitWidth: 100
implicitHeight: 100
opacity: enabled ? 1 : 0.3
color: control.down ? "#17a81a" : "#21be2b"
radius: size / 2
readonly property real size: Math.min(control.width, control.height)
width: size
height: size
anchors.centerIn: parent
Canvas {
id: canvas
anchors.fill: parent
Connections {
target: control
onProgressChanged: canvas.requestPaint()
}
onPaint: {
var ctx = getContext("2d")
ctx.clearRect(0, 0, width, height)
ctx.strokeStyle = "white"
ctx.lineWidth = parent.size / 20
ctx.beginPath()
var startAngle = Math.PI / 5 * 3
var endAngle = startAngle + control.progress * Math.PI / 5 * 9
ctx.arc(width / 2, height / 2, width / 2 - ctx.lineWidth / 2 - 2, startAngle, endAngle)
ctx.stroke()
}
}
}
} Настройка Dial
Dial состоит из двух визуальных элементов: фонового элемента и кнопки.
import QtQuick 2.6
import QtQuick.Controls 2.1
Dial {
id: control
background: Rectangle {
x: control.width / 2 - width / 2
y: control.height / 2 - height / 2
width: Math.max(64, Math.min(control.width, control.height))
height: width
color: "transparent"
radius: width / 2
border.color: control.pressed ? "#17a81a" : "#21be2b"
opacity: control.enabled ? 1 : 0.3
}
handle: Rectangle {
id: handleItem
x: control.background.x + control.background.width / 2 - width / 2
y: control.background.y + control.background.height / 2 - height / 2
width: 16
height: 16
color: control.pressed ? "#17a81a" : "#21be2b"
radius: 8
antialiasing: true
opacity: control.enabled ? 1 : 0.3
transform: [
Translate {
y: -Math.min(control.background.width, control.background.height) * 0.4 + handleItem.height / 2
},
Rotation {
angle: control.angle
origin.x: handleItem.width / 2
origin.y: handleItem.height / 2
}
]
}
} Настройка Drawer
Drawer может иметь визуальный фоновый элемент.
background: Rectangle {
Rectangle {
x: parent.width - 1
width: 1
height: parent.height
color: "#21be2b"
}
} Настройка Frame
Frame состоит из одного визуального элемента: фонового элемента.
import QtQuick 2.6
import QtQuick.Controls 2.1
Frame {
background: Rectangle {
color: "transparent"
border.color: "#21be2b"
radius: 2
}
Label {
text: qsTr("Content goes here!")
}
} Настройка GroupBox
GroupBox состоит из двух визуальных элементов: фонового элемента и метки.
import QtQuick 2.6
import QtQuick.Controls 2.1
GroupBox {
id: control
title: qsTr("GroupBox")
background: Rectangle {
y: control.topPadding - control.bottomPadding
width: parent.width
height: parent.height - control.topPadding + control.bottomPadding
color: "transparent"
border.color: "#21be2b"
radius: 2
}
label: Label {
x: control.leftPadding
width: control.availableWidth
text: control.title
color: "#21be2b"
elide: Text.ElideRight
}
Label {
text: qsTr("Content goes here!")
}
} Настройка ItemDelegate
ItemDelegate состоит из двух визуальных элементов: фонового элемента и элемента содержимого.
import QtQuick 2.6
import QtQuick.Controls 2.1
ItemDelegate {
id: control
text: qsTr("ItemDelegate")
contentItem: Text {
rightPadding: control.spacing
text: control.text
font: control.font
color: control.enabled ? (control.down ? "#17a81a" : "#21be2b") : "#bdbebf"
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
}
background: Rectangle {
implicitWidth: 100
implicitHeight: 40
opacity: enabled ? 1 : 0.3
color: control.down ? "#dddedf" : "#eeeeee"
Rectangle {
width: parent.width
height: 1
color: control.down ? "#17a81a" : "#21be2b"
anchors.bottom: parent.bottom
}
}
} Настройка Label
Label может иметь визуальный фоновый элемент.
import QtQuick 2.6
import QtQuick.Controls 2.1
Label {
text: qsTr("Label")
color: "#21be2b"
} Настройка Menu
- Menu состоит из визуального фонового элемента.
- MenuItem состоит из четырёх визуальных элементов: фонового, элемента содержимого, индикатора и стрелки.
- MenuSeparator состоит из визуального фонового и элемента содержимого.
import QtQuick 2.10
import QtQuick.Controls 2.3
Menu {
id: menu
Action { text: qsTr("Tool Bar"); checkable: true }
Action { text: qsTr("Side Bar"); checkable: true; checked: true }
Action { text: qsTr("Status Bar"); checkable: true; checked: true }
MenuSeparator {
contentItem: Rectangle {
implicitWidth: 200
implicitHeight: 1
color: "#21be2b"
}
}
Menu {
title: qsTr("Advanced")
// ...
}
topPadding: 2
bottomPadding: 2
delegate: MenuItem {
id: menuItem
implicitWidth: 200
implicitHeight: 40
arrow: Canvas {
x: parent.width - width
implicitWidth: 40
implicitHeight: 40
visible: menuItem.subMenu
onPaint: {
var ctx = getContext("2d")
ctx.fillStyle = menuItem.highlighted ? "#ffffff" : "#21be2b"
ctx.moveTo(15, 15)
ctx.lineTo(width - 15, height / 2)
ctx.lineTo(15, height - 15)
ctx.closePath()
ctx.fill()
}
}
indicator: Item {
implicitWidth: 40
implicitHeight: 40
Rectangle {
width: 26
height: 26
anchors.centerIn: parent
visible: menuItem.checkable
border.color: "#21be2b"
radius: 3
Rectangle {
width: 14
height: 14
anchors.centerIn: parent
visible: menuItem.checked
color: "#21be2b"
radius: 2
}
}
}
contentItem: Text {
leftPadding: menuItem.indicator.width
rightPadding: menuItem.arrow.width
text: menuItem.text
font: menuItem.font
opacity: enabled ? 1.0 : 0.3
color: menuItem.highlighted ? "#ffffff" : "#21be2b"
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
background: Rectangle {
implicitWidth: 200
implicitHeight: 40
opacity: enabled ? 1 : 0.3
color: menuItem.highlighted ? "#21be2b" : "transparent"
}
}
background: Rectangle {
implicitWidth: 200
implicitHeight: 40
color: "#ffffff"
border.color: "#21be2b"
radius: 2
}
} Настройка MenuBar
MenuBar может иметь визуальный фоновый элемент, а MenuBarItem состоит из двух визуальных элементов: фонового и элемента содержимого.
import QtQuick 2.10
import QtQuick.Controls 2.3
MenuBar {
id: menuBar
Menu { title: qsTr("File") }
Menu { title: qsTr("Edit") }
Menu { title: qsTr("View") }
Menu { title: qsTr("Help") }
delegate: MenuBarItem {
id: menuBarItem
contentItem: Text {
text: menuBarItem.text
font: menuBarItem.font
opacity: enabled ? 1.0 : 0.3
color: menuBarItem.highlighted ? "#ffffff" : "#21be2b"
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
background: Rectangle {
implicitWidth: 40
implicitHeight: 40
opacity: enabled ? 1 : 0.3
color: menuBarItem.highlighted ? "#21be2b" : "transparent"
}
}
background: Rectangle {
implicitWidth: 40
implicitHeight: 40
color: "#ffffff"
Rectangle {
color: "#21be2b"
width: parent.width
height: 1
anchors.bottom: parent.bottom
}
}
} Настройка PageIndicator
PageIndicator состоит из фонового элемента, элемента содержимого и элемента делегата.
import QtQuick 2.6
import QtQuick.Controls 2.1
PageIndicator {
id: control
count: 5
currentIndex: 2
delegate: Rectangle {
implicitWidth: 8
implicitHeight: 8
radius: width / 2
color: "#21be2b"
opacity: index === control.currentIndex ? 0.95 : pressed ? 0.7 : 0.45
Behavior on opacity {
OpacityAnimator {
duration: 100
}
}
}
} Настройка Pane
Pane состоит из фонового элемента.
import QtQuick 2.6
import QtQuick.Controls 2.1
Pane {
background: Rectangle {
color: "#eeeeee"
}
Label {
text: qsTr("Content goes here!")
}
} Настройка Popup
Popup состоит из фонового и элемента содержимого.
import QtQuick 2.6
import QtQuick.Controls 2.0
Popup {
id: popup
background: Rectangle {
implicitWidth: 200
implicitHeight: 200
border.color: "#444"
}
contentItem: Column {}
} Настройка ProgressBar
ProgressBar состоит из двух визуальных элементов: фонового и элемента содержимого.
import QtQuick 2.6
import QtQuick.Controls 2.1
ProgressBar {
id: control
value: 0.5
padding: 2
background: Rectangle {
implicitWidth: 200
implicitHeight: 6
color: "#e6e6e6"
radius: 3
}
contentItem: Item {
implicitWidth: 200
implicitHeight: 4
Rectangle {
width: control.visualPosition * parent.width
height: parent.height
radius: 2
color: "#17a81a"
}
}
} Настройка RadioButton
RadioButton состоит из трёх визуальных элементов: фонового, элемента содержимого и индикатора.
import QtQuick 2.6
import QtQuick.Controls 2.1
RadioButton {
id: control
text: qsTr("RadioButton")
checked: true
indicator: Rectangle {
implicitWidth: 26
implicitHeight: 26
x: control.leftPadding
y: parent.height / 2 - height / 2
radius: 13
border.color: control.down ? "#17a81a" : "#21be2b"
Rectangle {
width: 14
height: 14
x: 6
y: 6
radius: 7
color: control.down ? "#17a81a" : "#21be2b"
visible: control.checked
}
}
contentItem: Text {
text: control.text
font: control.font
opacity: enabled ? 1.0 : 0.3
color: control.down ? "#17a81a" : "#21be2b"
verticalAlignment: Text.AlignVCenter
leftPadding: control.indicator.width + control.spacing
}
} Настройка RadioDelegate
RadioDelegate состоит из трёх визуальных элементов: фонового, элемента содержимого и индикатора.
import QtQuick 2.6
import QtQuick.Controls 2.1
RadioDelegate {
id: control
text: qsTr("RadioDelegate")
checked: true
contentItem: Text {
rightPadding: control.indicator.width + control.spacing
text: control.text
font: control.font
opacity: enabled ? 1.0 : 0.3
color: control.down ? "#17a81a" : "#21be2b"
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
}
indicator: Rectangle {
implicitWidth: 26
implicitHeight: 26
x: control.width - width - control.rightPadding
y: parent.height / 2 - height / 2
radius: 13
color: "transparent"
border.color: control.down ? "#17a81a" : "#21be2b"
Rectangle {
width: 14
height: 14
x: 6
y: 6
radius: 7
color: control.down ? "#17a81a" : "#21be2b"
visible: control.checked
}
}
background: Rectangle {
implicitWidth: 100
implicitHeight: 40
visible: control.down || control.highlighted
color: control.down ? "#bdbebf" : "#eeeeee"
}
} Настройка RangeSlider
RangeSlider состоит из трёх визуальных элементов: фонового, первой ручки и второй ручки.
import QtQuick 2.6
import QtQuick.Controls 2.1
RangeSlider {
id: control
first.value: 0.25
second.value: 0.75
background: Rectangle {
x: control.leftPadding
y: control.topPadding + control.availableHeight / 2 - height / 2
implicitWidth: 200
implicitHeight: 4
width: control.availableWidth
height: implicitHeight
radius: 2
color: "#bdbebf"
Rectangle {
x: control.first.visualPosition * parent.width
width: control.second.visualPosition * parent.width - x
height: parent.height
color: "#21be2b"
radius: 2
}
}
first.handle: Rectangle {
x: control.leftPadding + first.visualPosition * (control.availableWidth - width)
y: control.topPadding + control.availableHeight / 2 - height / 2
implicitWidth: 26
implicitHeight: 26
radius: 13
color: first.pressed ? "#f0f0f0" : "#f6f6f6"
border.color: "#bdbebf"
}
second.handle: Rectangle {
x: control.leftPadding + second.visualPosition * (control.availableWidth - width)
y: control.topPadding + control.availableHeight / 2 - height / 2
implicitWidth: 26
implicitHeight: 26
radius: 13
color: second.pressed ? "#f0f0f0" : "#f6f6f6"
border.color: "#bdbebf"
}
} Настройка RoundButton
RoundButton можно настраивать так же, как и кнопку.
Настройка ScrollBar
ScrollBar состоит из двух визуальных элементов: фонового и элемента содержимого.
import QtQuick 2.6
import QtQuick.Controls 2.1
ScrollBar {
id: control
size: 0.3
position: 0.2
active: true
orientation: Qt.Vertical
contentItem: Rectangle {
implicitWidth: 6
implicitHeight: 100
radius: width / 2
color: control.pressed ? "#81e889" : "#c2f4c6"
}
} Настройка ScrollIndicator
ScrollIndicator состоит из двух визуальных элементов: фонового и элемента содержимого.
import QtQuick 2.6
import QtQuick.Controls 2.1
ScrollIndicator {
id: control
size: 0.3
position: 0.2
active: true
orientation: Qt.Vertical
contentItem: Rectangle {
implicitWidth: 2
implicitHeight: 100
color: "#c2f4c6"
}
} Настройка ScrollView
ScrollView состоит из фонового элемента и горизонтальной и вертикальной полос прокрутки.
ScrollView {
id: control
width: 200
height: 200
focus: true
Label {
text: "ABC"
font.pixelSize: 224
}
ScrollBar.vertical: ScrollBar {
parent: control
x: control.mirrored ? 0 : control.width - width
y: control.topPadding
height: control.availableHeight
active: control.ScrollBar.horizontal.active
}
ScrollBar.horizontal: ScrollBar {
parent: control
x: control.leftPadding
y: control.height - height
width: control.availableWidth
active: control.ScrollBar.vertical.active
}
background: Rectangle {
border.color: control.activeFocus ? "#21be2b" : "#bdbebf"
}
} Настройка Slider
Slider состоит из двух визуальных элементов: фонового и ручки.
import QtQuick 2.6
import QtQuick.Controls 2.1
Slider {
id: control
value: 0.5
background: Rectangle {
x: control.leftPadding
y: control.topPadding + control.availableHeight / 2 - height / 2
implicitWidth: 200
implicitHeight: 4
width: control.availableWidth
height: implicitHeight
radius: 2
color: "#bdbebf"
Rectangle {
width: control.visualPosition * parent.width
height: parent.height
color: "#21be2b"
radius: 2
}
}
handle: Rectangle {
x: control.leftPadding + control.visualPosition * (control.availableWidth - width)
y: control.topPadding + control.availableHeight / 2 - height / 2
implicitWidth: 26
implicitHeight: 26
radius: 13
color: control.pressed ? "#f0f0f0" : "#f6f6f6"
border.color: "#bdbebf"
}
} Настройка SpinBox
SpinBox состоит из четырёх визуальных элементов: фонового, элемента содержимого, индикатора увеличения и индикатора уменьшения.
import QtQuick 2.6
import QtQuick.Controls 2.1
SpinBox {
id: control
value: 50
editable: true
contentItem: TextInput {
z: 2
text: control.textFromValue(control.value, control.locale)
font: control.font
color: "#21be2b"
selectionColor: "#21be2b"
selectedTextColor: "#ffffff"
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
readOnly: !control.editable
validator: control.validator
inputMethodHints: Qt.ImhFormattedNumbersOnly
}
up.indicator: Rectangle {
x: control.mirrored ? 0 : parent.width - width
height: parent.height
implicitWidth: 40
implicitHeight: 40
color: control.up.pressed ? "#e4e4e4" : "#f6f6f6"
border.color: enabled ? "#21be2b" : "#bdbebf"
Text {
text: "+"
font.pixelSize: control.font.pixelSize * 2
color: "#21be2b"
anchors.fill: parent
fontSizeMode: Text.Fit
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
down.indicator: Rectangle {
x: control.mirrored ? parent.width - width : 0
height: parent.height
implicitWidth: 40
implicitHeight: 40
color: control.down.pressed ? "#e4e4e4" : "#f6f6f6"
border.color: enabled ? "#21be2b" : "#bdbebf"
Text {
text: "-"
font.pixelSize: control.font.pixelSize * 2
color: "#21be2b"
anchors.fill: parent
fontSizeMode: Text.Fit
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
background: Rectangle {
implicitWidth: 140
border.color: "#bdbebf"
}
} Настройка StackView
StackView может иметь визуальный фоновый элемент, а также позволяет настраивать переходы, используемые для операций push, pop и replace.
import QtQuick 2.6
import QtQuick.Controls 2.1
StackView {
id: control
popEnter: Transition {
XAnimator {
from: (control.mirrored ? -1 : 1) * -control.width
to: 0
duration: 400
easing.type: Easing.OutCubic
}
}
popExit: Transition {
XAnimator {
from: 0
to: (control.mirrored ? -1 : 1) * control.width
duration: 400
easing.type: Easing.OutCubic
}
}
} Настройка SwipeDelegate
SwipeDelegate состоит из шести визуальных элементов: фонового, элемента содержимого, индикатора, swipe.left, swipe.right, и swipe.behind.
import QtQuick 2.6
import QtQuick.Controls 2.1
SwipeDelegate {
id: control
text: qsTr("SwipeDelegate")
Component {
id: component
Rectangle {
color: SwipeDelegate.pressed ? "#333" : "#444"
width: parent.width
height: parent.height
clip: true
Label {
text: qsTr("Press me!")
color: "#21be2b"
anchors.centerIn: parent
}
}
}
swipe.left: component
swipe.right: component
contentItem: Text {
text: control.text
font: control.font
color: control.enabled ? (control.down ? "#17a81a" : "#21be2b") : "#bdbebf"
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
Behavior on x {
enabled: !control.down
NumberAnimation {
easing.type: Easing.InOutCubic
duration: 400
}
}
}
} Настройка SwipeView
SwipeView может иметь визуальный фоновый элемент. Навигация реализована с помощью элемента содержимого.
import QtQuick 2.6
import QtQuick.Controls 2.1
SwipeView {
id: control
background: Rectangle {
color: "#eeeeee"
}
} Настройка Switch
Switch состоит из трёх визуальных элементов: фонового, элемента содержимого и индикатора.
import QtQuick 2.6
import QtQuick.Controls 2.1
Switch {
id: control
text: qsTr("Switch")
indicator: Rectangle {
implicitWidth: 48
implicitHeight: 26
x: control.leftPadding
y: parent.height / 2 - height / 2
radius: 13
color: control.checked ? "#17a81a" : "#ffffff"
border.color: control.checked ? "#17a81a" : "#cccccc"
Rectangle {
x: control.checked ? parent.width - width : 0
width: 26
height: 26
radius: 13
color: control.down ? "#cccccc" : "#ffffff"
border.color: control.checked ? (control.down ? "#17a81a" : "#21be2b") : "#999999"
}
}
contentItem: Text {
text: control.text
font: control.font
opacity: enabled ? 1.0 : 0.3
color: control.down ? "#17a81a" : "#21be2b"
verticalAlignment: Text.AlignVCenter
leftPadding: control.indicator.width + control.spacing
}
} Настройка SwitchDelegate
SwitchDelegate состоит из трёх визуальных элементов: фонового, элемента содержимого и индикатора.
import QtQuick 2.6
import QtQuick.Controls 2.1
SwitchDelegate {
id: control
text: qsTr("SwitchDelegate")
checked: true
contentItem: Text {
rightPadding: control.indicator.width + control.spacing
text: control.text
font: control.font
opacity: enabled ? 1.0 : 0.3
color: control.down ? "#17a81a" : "#21be2b"
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
}
indicator: Rectangle {
implicitWidth: 48
implicitHeight: 26
x: control.width - width - control.rightPadding
y: parent.height / 2 - height / 2
radius: 13
color: control.checked ? "#17a81a" : "transparent"
border.color: control.checked ? "#17a81a" : "#cccccc"
Rectangle {
x: control.checked ? parent.width - width : 0
width: 26
height: 26
radius: 13
color: control.down ? "#cccccc" : "#ffffff"
border.color: control.checked ? (control.down ? "#17a81a" : "#21be2b") : "#999999"
}
}
background: Rectangle {
implicitWidth: 100
implicitHeight: 40
visible: control.down || control.highlighted
color: control.down ? "#bdbebf" : "#eeeeee"
}
} Настройка TabBar
TabBar состоит из двух визуальных элементов: фонового и элемента содержимого.
import QtQuick 2.6
import QtQuick.Controls 2.1
TabBar {
id: control
background: Rectangle {
color: "#eeeeee"
}
TabButton {
text: qsTr("Home")
}
TabButton {
text: qsTr("Discover")
}
TabButton {
text: qsTr("Activity")
}
} Настройка TabButton
TabButton можно настраивать так же, как и кнопку.
Настройка TextArea
TextArea состоит из фонового элемента.
import QtQuick 2.6
import QtQuick.Controls 2.1
TextArea {
id: control
placeholderText: qsTr("Enter description")
background: Rectangle {
implicitWidth: 200
implicitHeight: 40
border.color: control.enabled ? "#21be2b" : "transparent"
}
} Настройка TextField
TextField состоит из фонового элемента.
import QtQuick 2.6
import QtQuick.Controls 2.1
TextField {
id: control
placeholderText: qsTr("Enter description")
background: Rectangle {
implicitWidth: 200
implicitHeight: 40
color: control.enabled ? "transparent" : "#353637"
border.color: control.enabled ? "#21be2b" : "transparent"
}
} Настройка ToolBar
ToolBar состоит из одного визуального элемента: фонового элемента.
ToolBar {
id: control
background: Rectangle {
implicitHeight: 40
color: "#eeeeee"
Rectangle {
width: parent.width
height: 1
anchors.bottom: parent.bottom
color: "transparent"
border.color: "#21be2b"
}
}
RowLayout {
anchors.fill: parent
ToolButton {
text: qsTr("Undo")
}
ToolButton {
text: qsTr("Redo")
}
}
} Настройка ToolButton
Кнопка инструмента состоит из двух визуальных элементов: фон и элемент содержимого.
import QtQuick 2.6
import QtQuick.Controls 2.1
ToolButton {
id: control
text: qsTr("ToolButton")
width: 120
contentItem: Text {
text: control.text
font: control.font
opacity: enabled ? 1.0 : 0.3
color: control.down ? "#17a81a" : "#21be2b"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
background: Rectangle {
implicitWidth: 40
implicitHeight: 40
color: Qt.darker("#33333333", control.enabled && (control.checked || control.highlighted) ? 1.5 : 1.0)
opacity: enabled ? 1 : 0.3
visible: control.down || (control.enabled && (control.checked || control.highlighted))
}
} Настройка разделителя инструментов
Разделитель инструментов состоит из двух визуальных элементов: фон и элемент содержимого.
ToolBar {
RowLayout {
anchors.fill: parent
ToolButton {
text: qsTr("Action 1")
}
ToolButton {
text: qsTr("Action 2")
}
ToolSeparator {
padding: vertical ? 10 : 2
topPadding: vertical ? 2 : 10
bottomPadding: vertical ? 2 : 10
contentItem: Rectangle {
implicitWidth: parent.vertical ? 1 : 24
implicitHeight: parent.vertical ? 24 : 1
color: "#c3c3c3"
}
}
ToolButton {
text: qsTr("Action 3")
}
ToolButton {
text: qsTr("Action 4")
}
Item {
Layout.fillWidth: true
}
}
} Настройка всплывающей подсказки
Всплывающая подсказка состоит из двух визуальных элементов: фон и элемент содержимого.
import QtQuick 2.6
import QtQuick.Controls 2.1
ToolTip {
id: control
text: qsTr("A descriptive tool tip of what the button does")
contentItem: Text {
text: control.text
font: control.font
color: "#21be2b"
}
background: Rectangle {
border.color: "#21be2b"
}
} Настройка регулятора
Регулятор состоит из трёх визуальных элементов: фон, contentItem и делегат.
import QtQuick 2.6
import QtQuick.Controls 2.1
Tumbler {
id: control
model: 15
background: Item {
Rectangle {
opacity: control.enabled ? 0.2 : 0.1
border.color: "#000000"
width: parent.width
height: 1
anchors.top: parent.top
}
Rectangle {
opacity: control.enabled ? 0.2 : 0.1
border.color: "#000000"
width: parent.width
height: 1
anchors.bottom: parent.bottom
}
}
delegate: Text {
text: qsTr("Item %1").arg(modelData + 1)
font: control.font
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
opacity: 1.0 - Math.abs(Tumbler.displacement) / (control.visibleItemCount / 2)
}
Rectangle {
anchors.horizontalCenter: control.horizontalCenter
y: control.height * 0.4
width: 40
height: 1
color: "#21be2b"
}
Rectangle {
anchors.horizontalCenter: control.horizontalCenter
y: control.height * 0.6
width: 40
height: 1
color: "#21be2b"
}
} Если вы хотите определить свой собственный элемент содержимого, используйте либо ListView, либо PathView в качестве корневого элемента. Для обертывающего регулятора используйте PathView:
Tumbler {
id: tumbler
contentItem: PathView {
id: pathView
model: tumbler.model
delegate: tumbler.delegate
clip: true
pathItemCount: tumbler.visibleItemCount + 1
preferredHighlightBegin: 0.5
preferredHighlightEnd: 0.5
dragMargin: width / 2
path: Path {
startX: pathView.width / 2
startY: -pathView.delegateHeight / 2
PathLine {
x: pathView.width / 2
y: pathView.pathItemCount * pathView.delegateHeight - pathView.delegateHeight / 2
}
}
property real delegateHeight: tumbler.availableHeight / tumbler.visibleItemCount
}
} Для регулятора без обертки используйте ListView:
Tumbler {
id: tumbler
contentItem: ListView {
model: tumbler.model
delegate: tumbler.delegate
snapMode: ListView.SnapToItem
highlightRangeMode: ListView.StrictlyEnforceRange
preferredHighlightBegin: height / 2 - (height / tumbler.visibleItemCount / 2)
preferredHighlightEnd: height / 2 + (height / tumbler.visibleItemCount / 2)
clip: true
}
}
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/archives/qt-5.11/qtquickcontrols2-customize.html