Стиль CircularGauge
Компонент стрелки
Компонент needle вращается вокруг шкалы для отображения текущего значения.
Начиная с базового стиля, добавим простую белую стрелку:
needle: Rectangle {
y: outerRadius * 0.15
implicitWidth: outerRadius * 0.03
implicitHeight: outerRadius * 0.9
antialiasing: true
color: "#e5e5e5"
} Как указано в документации для CircularGaugeStyle, необходимо установить свойства implicitWidth и implicitHeight. Это необходимо для правильного позиционирования стрелки. Мы всегда масштабируем элементы относительно свойства outerRadius стиля, обеспечивая плавное изменение размеров управления.
Смещаем стрелку по вертикали, чтобы ее задняя часть находилась за кнопкой.
Компонент переднего плана
Мы изменили стрелку, но кнопка по-прежнему стандартная; заменим её. Компонент foreground определяет стандартную кнопку, поэтому мы можем указать свою, переопределив её (мы также можем установить её в null, если не хотим переднего плана):
foreground: Item {
Rectangle {
width: outerRadius * 0.2
height: width
radius: width / 2
color: "#e5e5e5"
anchors.centerIn: parent
}
} Сначала создаём окружность из элемента Rectangle, установив радиус, равный половине ширины (можно использовать ширину или высоту; в данном случае они всегда равны). Мы делаем его дочерним элементом Item, так как передний план заполняет шкалу. Затем центрируем его внутри Item.
Устанавливаем цвет кнопки тем же белым, что и стрелка.
Компонент метки делений
Предположим, мы хотим предупредить пользователя, если значение, отображаемое шкалой, выходит за определённый диапазон. Мы можем представить этот диапазон пользователю несколькими способами:
- Изменить цвет делений в зависимости от
styleData.value - Добавить изображение в фон
- Отобразить с помощью Canvas
Выберем варианты 1 и 3, так как они более гибкие, чем использование изображения.
Сначала изменим цвет трёх верхних меток делений:
tickmarkLabel: Text {
font.pixelSize: Math.max(6, outerRadius * 0.1)
text: styleData.value
color: styleData.value >= 80 ? "#e34c22" : "#e5e5e5"
antialiasing: true
} Также изменим цвет остальных меток на тот же белый, что и стрелка и кнопка.
Компонент делений
Теперь сделаем то же самое для трёх верхних делений:
tickmark: Rectangle {
visible: styleData.value < 80 || styleData.value % 10 == 0
implicitWidth: outerRadius * 0.02
antialiasing: true
implicitHeight: outerRadius * 0.06
color: styleData.value >= 80 ? "#e34c22" : "#e5e5e5"
} Компонент мелких делений
Для мелких делений отобразим только те, которые не превышают 80:
minorTickmark: Rectangle {
visible: styleData.value < 80
implicitWidth: outerRadius * 0.01
antialiasing: true
implicitHeight: outerRadius * 0.03
color: "#e5e5e5"
} Это потому, что в следующем разделе мы нарисуем что-то между этим диапазоном.
Компонент фона
Отобразим диапазон, указывающий на необходимость предосторожности, оранжевой дугой:
function degreesToRadians(degrees) {
return degrees * (Math.PI / 180);
}
background: Canvas {
onPaint: {
var ctx = getContext("2d");
ctx.reset();
ctx.beginPath();
ctx.strokeStyle = "#e34c22";
ctx.lineWidth = outerRadius * 0.02;
ctx.arc(outerRadius, outerRadius, outerRadius - ctx.lineWidth / 2,
degreesToRadians(valueToAngle(80) - 90), degreesToRadians(valueToAngle(100) - 90));
ctx.stroke();
}
} Определяем функцию преобразования градусов в радианы, которые используются в Canvas.
Далее, рисуем диапазон с помощью Canvas. Рисуем дугу между 80 и 100, используя функцию valueToAngle(), предоставленную CircularGaugeStyle. Обратите внимание, что мы вычитаем 90 градусов перед преобразованием в радианы, так как наш ноль — север, а у Canvas — восток.
Конечный результат:
Полный код этого примера:
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Extras 1.4
import QtQuick.Extras.Private 1.0
Rectangle {
width: 300
height: 300
color: "#494d53"
CircularGauge {
id: gauge
anchors.centerIn: parent
style: CircularGaugeStyle {
id: style
function degreesToRadians(degrees) {
return degrees * (Math.PI / 180);
}
background: Canvas {
onPaint: {
var ctx = getContext("2d");
ctx.reset();
ctx.beginPath();
ctx.strokeStyle = "#e34c22";
ctx.lineWidth = outerRadius * 0.02;
ctx.arc(outerRadius, outerRadius, outerRadius - ctx.lineWidth / 2,
degreesToRadians(valueToAngle(80) - 90), degreesToRadians(valueToAngle(100) - 90));
ctx.stroke();
}
}
tickmark: Rectangle {
visible: styleData.value < 80 || styleData.value % 10 == 0
implicitWidth: outerRadius * 0.02
antialiasing: true
implicitHeight: outerRadius * 0.06
color: styleData.value >= 80 ? "#e34c22" : "#e5e5e5"
}
minorTickmark: Rectangle {
visible: styleData.value < 80
implicitWidth: outerRadius * 0.01
antialiasing: true
implicitHeight: outerRadius * 0.03
color: "#e5e5e5"
}
tickmarkLabel: Text {
font.pixelSize: Math.max(6, outerRadius * 0.1)
text: styleData.value
color: styleData.value >= 80 ? "#e34c22" : "#e5e5e5"
antialiasing: true
}
needle: Rectangle {
y: outerRadius * 0.15
implicitWidth: outerRadius * 0.03
implicitHeight: outerRadius * 0.9
antialiasing: true
color: "#e5e5e5"
}
foreground: Item {
Rectangle {
width: outerRadius * 0.2
height: width
radius: width / 2
color: "#e5e5e5"
anchors.centerIn: parent
}
}
}
}
}
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.14/styling-circulargauge.html