Spec-Zone.ru › Qt 5.15

Стиль 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.

Устанавливаем цвет кнопки тем же белым, что и стрелка.

Компонент метки делений

Предположим, мы хотим предупредить пользователя, если значение, отображаемое шкалой, выходит за определённый диапазон. Мы можем представить этот диапазон пользователю несколькими способами:

  1. Изменить цвет делений в зависимости от styleData.value
  2. Добавить изображение в фон
  3. Отобразить с помощью Canvas

Выберем варианты 1 и 3, так как они более гибкие, чем использование изображения.

Сначала изменим цвет трёх верхних меток делений:

tickmarkLabel:  Text {
    font.pixelSize: Math.max(6, outerRadius * 0.1)
    text: styleData.value
    color: styleData.value >= 80 ? "#e34c22" : "#e5e5e5"
    antialiasing: true
}

tickmarkLabel

Также изменим цвет остальных меток на тот же белый, что и стрелка и кнопка.

Компонент делений

Теперь сделаем то же самое для трёх верхних делений:

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"
}

tickmark

Компонент мелких делений

Для мелких делений отобразим только те, которые не превышают 80:

minorTickmark: Rectangle {
    visible: styleData.value < 80
    implicitWidth: outerRadius * 0.01
    antialiasing: true
    implicitHeight: outerRadius * 0.03
    color: "#e5e5e5"
}

minorTickmark

Это потому, что в следующем разделе мы нарисуем что-то между этим диапазоном.

Компонент фона

Отобразим диапазон, указывающий на необходимость предосторожности, оранжевой дугой:

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 — восток.

Конечный результат:

background

Полный код этого примера:

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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API