Настройка элементов управления 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в качестве стиля, например.
По умолчанию система стилей использует стиль Default в качестве резервного варианта для элементов управления, которые не реализованы. Для настройки или расширения любого другого встроенного стиля можно указать другой резервный стиль, используя QQuickStyle.
Это означает, что вы можете реализовать любое количество элементов управления для своего пользовательского стиля и разместить их практически где угодно. Это также позволяет пользователям создавать свои собственные стили для вашего приложения.
Расширения стиля на 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 состоит из background, content item, popup, indicator и delegate.
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 состоит из двух визуальных элементов: background и content item.
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
Поворотный регулятор состоит из двух визуальных элементов: фонового и маркерного.
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
}
]
}
} Настройка выдвижного меню
Выдвижное меню может иметь визуальный элемент фона.
background: Rectangle {
Rectangle {
x: parent.width - 1
width: 1
height: parent.height
color: "#21be2b"
}
} Настройка рамки
Рамка состоит из одного визуального элемента: фонового.
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!")
}
} Настройка группового поля
Групповое поле состоит из двух визуальных элементов: фонового и метки.
import QtQuick 2.6
import QtQuick.Controls 2.1
GroupBox {
id: control
title: qsTr("GroupBox")
background: Rectangle {
y: control.topPadding - control.padding
width: parent.width
height: parent.height - control.topPadding + control.padding
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!")
}
} Настройка делегата элемента
Делегат элемента состоит из двух визуальных элементов: фонового и элемента содержимого.
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
}
}
} Настройка метки
Метка может иметь визуальный элемент фона.
import QtQuick 2.6
import QtQuick.Controls 2.1
Label {
text: qsTr("Label")
color: "#21be2b"
} Настройка меню
Меню состоит из элемента содержимого.
import QtQuick 2.6
import QtQuick.Controls 2.1
Menu {
id: menu
background: Rectangle {
implicitWidth: 200
implicitHeight: 200
color: "#ffffff"
border.color: "#353637"
}
MenuItem {
text: qsTr("New...")
}
MenuItem {
text: qsTr("Open...")
}
MenuItem {
text: qsTr("Save")
}
} Настройка пункта меню
Пункт меню можно настраивать так же, как и кнопку.
Настройка разделителя меню
Разделитель меню состоит из двух визуальных элементов: фонового и элемента содержимого.
import QtQuick 2.6
import QtQuick.Controls 2.1
Menu {
id: menu
MenuItem {
text: qsTr("New...")
}
MenuItem {
text: qsTr("Open...")
}
MenuItem {
text: qsTr("Save")
}
MenuSeparator {
padding: 0
topPadding: 12
bottomPadding: 12
contentItem: Rectangle {
implicitWidth: 200
implicitHeight: 1
color: "#1E000000"
}
}
MenuItem {
text: qsTr("Exit")
}
} Настройка индикатора страниц
Индикатор страниц состоит из фонового, элемента содержимого и делегата.
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
}
}
}
} Настройка панели
Панель состоит из фонового элемента.
import QtQuick 2.6
import QtQuick.Controls 2.1
Pane {
background: Rectangle {
color: "#eeeeee"
}
Label {
text: qsTr("Content goes here!")
}
} Настройка всплывающего окна
Всплывающее окно состоит из фонового и элемента содержимого.
import QtQuick 2.6
import QtQuick.Controls 2.0
Popup {
id: popup
background: Rectangle {
implicitWidth: 200
implicitHeight: 200
border.color: "#444"
}
contentItem: Column {}
} Настройка прогресс-бара
Прогресс-бар состоит из двух визуальных элементов: фонового и элемента содержимого.
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"
}
}
} Настройка радиокнопки
Радиокнопка состоит из трех визуальных элементов: фонового, элемента содержимого и индикатора.
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
}
} Настройка делегата радиокнопки
Делегат радиокнопки состоит из трех визуальных элементов: фонового, элемента содержимого и индикатора.
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"
}
} Настройка ползунка диапазона
Ползунок диапазона состоит из трех визуальных элементов: фонового, первого ползунка и второго ползунка.
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"
}
} Настройка круглой кнопки
Круглая кнопка можно настраивать так же, как и кнопку.
Настройка полосы прокрутки
Полоса прокрутки состоит из двух визуальных элементов: фонового и элемента содержимого.
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"
}
} Настройка индикатора прокрутки
Индикатор прокрутки состоит из двух визуальных элементов: фонового и элемента содержимого.
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 {
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"
}
} Настройка ползунка
Ползунок состоит из двух визуальных элементов: фонового и ползунка.
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"
}
} Настройка поля ввода
Поле ввода состоит из четырех визуальных элементов: фонового, элемента содержимого, верхнего индикатора и нижнего индикатора.
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"
}
} Настройка стека представлений
Стек представлений может иметь визуальный фоновый элемент, и позволяет настраивать переходы, используемые для операций 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
}
}
} Настройка делегата свайпа
Делегат свайпа состоит из шести визуальных элементов: фонового, элемента содержимого, индикатора, 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
}
}
}
} Настройка области свайпа
Область свайпа может иметь визуальный фоновый элемент. Навигация реализована с помощью элемента содержимого.
import QtQuick 2.6
import QtQuick.Controls 2.1
SwipeView {
id: control
background: Rectangle {
color: "#eeeeee"
}
} Настройка переключателя
Переключатель состоит из трех визуальных элементов: фонового, элемента содержимого и индикатора.
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
}
} Настройка делегата переключателя
Делегат переключателя состоит из трех визуальных элементов: фонового, элемента содержимого и индикатора.
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"
}
} Настройка панели вкладок
Панель вкладок состоит из двух визуальных элементов: фонового и элемента содержимого.
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")
}
} Настройка кнопки вкладки
Кнопка вкладки можно настраивать так же, как и кнопку.
Настройка области текста
Область текста состоит из фонового элемента.
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"
}
} Настройка поля ввода
Поле ввода состоит из фонового элемента.
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 {
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")
}
}
} Настройка инструментальной кнопки
Инструментальная кнопка состоит из двух визуальных элементов: фонового и элемента содержимого.
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"
}
} Настройка ползунка
Ползунок состоит из трех визуальных элементов: фонового, элемента содержимого и делегата.
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"
}
} Если вы хотите определить собственный элемент содержимого, используйте список элементов или просмотр по пути в качестве корневого элемента. Для обертывающего ползунка используйте просмотр по пути:
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
}
} Для необорачивающегося ползунка используйте список элементов:
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/qt-5.9/qtquickcontrols2-customize.html