Russian Qt Forum
Февраля 19, 2025, 01:06 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Обьект для отображения циферблата  (Прочитано 6129 раз)
8: Undefined index: LANG_NAME
Файл: /var/www/html/Sources/geshi/geshi.php
Строка: 4032
SektorCT
Частый гость
***
Offline Offline

Сообщений: 229


Просмотр профиля
« : Июня 20, 2023, 15:35 »

Добрый день всем.
Нужно нарисовтаь циферблат, разные значения, 2 стрелки. Нашел что в qml есть Canvas.
Вопрос к тем кто с подобным сталкивался, какова производительность если через него делать? Есть ли другие способы создание такого обьекта? Если будет штук 10-20 таких обьектов как сильно может пострадать производительность?
Само собою все значения, изменения и вся логика будет только на строне С++.

Спасибо.
Записан
SektorCT
Частый гость
***
Offline Offline

Сообщений: 229


Просмотр профиля
« Ответ #1 : Июня 21, 2023, 12:58 »

Может кто использовал QSGGeometryNode, с его помощью можно такое нарисовтаь?
Записан
SektorCT
Частый гость
***
Offline Offline

Сообщений: 229


Просмотр профиля
« Ответ #2 : Июня 26, 2023, 12:16 »

Нашел один пример в котормо изпользуется обьект Shape
И получилось такое сделать

Код:
Shape {
        id: trackShape

        height: appWin.height
        layer.enabled: true
        layer.samples: 8
        visible: !appWin.hideTrack
        width: appWin.width

        ShapePath {
            id: trackShapePath

            capStyle: appWin.capStyle
            fillColor: internal.transparentColor
            strokeColor: appWin.trackColor
            strokeWidth: appWin.trackWidth

            PathAngleArc {
                centerX: appWin.width / 2
                centerY: appWin.height / 2
                radiusX: internal.baseRadius
                radiusY: internal.baseRadius
                startAngle: appWin.startAngle - 90
                sweepAngle: internal.actualSpanAngle
            }
        }
    }

https://ibb.co/Q6nW1kv

А мне надо бы вот до такого примерно довести. То есть шкалы и стрелка, какой то центральынй круглый обьект в котором будут значения более точные.
Может кто подскажет как стрелки и шкалы создать?
https://ibb.co/9yzZgZR

Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #3 : Июня 26, 2023, 15:34 »

шкалы (и стрелки) — это, очевидно, просто линии PathLine. или надо еще написать код как ходить по кругу чтоб их проставить? Улыбающийся
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
SektorCT
Частый гость
***
Offline Offline

Сообщений: 229


Просмотр профиля
« Ответ #4 : Июля 04, 2023, 16:22 »

В общем поулчилось сделать и Shape сам внешнйи круг и для каждого tickmark высчитан угол наклона. Но вот он ивсе у меня распологаются в центре.
https://ibb.co/mDL2X00

Может кто скажет как якарями привязать к внутренней строне дуги чтоыб тики рапологались правильно? Или можно по другому?
Ниже код:
Код:
Shape
        {
            id: trackShape
            height:        appWin.size
            width:         appWin.size
            layer.enabled: true
            layer.samples: 8
            rotation:      180

            ShapePath
            {
                id: trackShapePath
                capStyle:    Qt.FlatCap
                fillColor:   "transparent"
                strokeColor: "#333333"
                strokeWidth: pelData.mainCircleBorderSize

                PathAngleArc
                {
                    centerX:    appWin.size / 2
                    centerY:    appWin.size / 2
                    radiusX:    Math.min(appWin.size, appWin.size) / 2 - Math.max(appWin.trackWidth, appWin.progressWidth) / 2
                    radiusY:    Math.min(appWin.size, appWin.size) / 2 - Math.max(appWin.trackWidth, appWin.progressWidth) / 2
                    startAngle: appWin.startAngle - 90
                    sweepAngle: 320 - 40
                }
            }
        }

        Rectangle
        {
            id: mainForeground
            z:                1
            anchors.centerIn: mainItem
            height:           pelData.centralCircleRadius
            width:            pelData.centralCircleRadius
            color:            "gray"
            border.width:     pelData.secondCircleBorderSize
            border.color:     "#505050"
            radius:           height / 2
            visible: false

            Text
            {
                id: textValue
                z:                1
                anchors.centerIn: parent
                text:             pelData.currentValue
                font.pixelSize:   pelData.textValueSize
                font.bold:        true
            }
        }

        Repeater
        {
            id: repeaterTickMark

            model: pelData.gaugeDataModel
            anchors.fill: parent

            delegate: Rectangle
            {
                width:        model.eWidth
                height:       model.eHeight
                color:        model.eColorTickMark
                antialiasing: true

                function major()
                {
                    if(model.eWithText)
                        return true
                    return false
                }

                Rectangle
                {
                    anchors.fill:         parent
                    anchors.topMargin:    major() ? 160 : 165
                    anchors.bottomMargin: major() ? 3 : 23
                    color:                "blue"

                    Component.onCompleted:
                    {
                        console.log(model.eAngle, model.index, model.eWidth, model.eWithText)
                    }
                }

                transform:
                [
                    Rotation
                    {
                        angle: model.eAngle
                    },
                    Translate {
                        x: mainItem.width  / 2
                        y: mainItem.height / 2
                    }
                ]
            }
        }
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #5 : Июля 04, 2023, 21:44 »

можно ж просто сместить координату на толщину дуги
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
SektorCT
Частый гость
***
Offline Offline

Сообщений: 229


Просмотр профиля
« Ответ #6 : Июля 05, 2023, 11:08 »

можно ж просто сместить координату на толщину дуги
А вы не могли бы примером написать как это можно сделать? не представлю пока.
И такой вопрос, мне надо будет к мажорным тикмаркам еще приделать надпись, значение его. Как понимаю это можно так же будет сделать как вы описали?
Записан
SektorCT
Частый гость
***
Offline Offline

Сообщений: 229


Просмотр профиля
« Ответ #7 : Июля 05, 2023, 14:08 »

Смысл такой что мне надо со внутренней стороны дуги разместить мажорные и минорные тикмарки. они будут иметь разную длину. И вот задумка была что они все рипетером раскиданы, а внутри уже видимая цветная часть с разными размерами. Потом уже и надписи со значениями у мажорных будут, но это второстепенное.
Записан
SektorCT
Частый гость
***
Offline Offline

Сообщений: 229


Просмотр профиля
« Ответ #8 : Июля 07, 2023, 15:55 »

Ниже код в котормо я пытаюсь с помощью PathMultiline  размещать нужные мне тикмарки. То есть я на месте второго Shape хочу и разместить тики. И поулчается тчо надо и постояныне расчеты делать если обьект еняет размер.
В приведенном коде в  PathMultiline я просто для реста пробую на основе 2 хотябы тиков создать в нужном месте. Мне уже посоветовали что надо по теории Пифагора искать. Могли бы на этмо примере показать если вы знаете как это можно сделать?

Код:
import QtQuick
import QtQuick.Controls
import QtQuick.Shapes

Item {
    id: appWin

    property int  progressWidth:    20
    property int  trackWidth:       3
    property int  handleHeight:     22
    property int  handleWidth:      22
    property real outerRadius:      15.0
    property real minorInsetRadius: outerRadius - 20
    property real majorInsetRadius: outerRadius - 20
    property real labelInsetRadius: outerRadius - 30

    // control param
    property double minimumValue:   0.0
    property double maximumValue:   160.0
    property real   startAngle:     40
    property real   endAngle:       320
    property double value

    property int    size:           appWin.height

    property real needleRotation: {
        var percentage = (appWin.value - appWin.minimumValue) /
                         (appWin.maximumValue - appWin.minimumValue);
        appWin.startAngle + percentage * Math.abs(appWin.endAngle - appWin.startAngle);
    }

    Item {
        id: mainItem
        anchors.horizontalCenter: appWin.horizontalCenter
        anchors.verticalCenter:   appWin.verticalCenter
        height:                   appWin.size
        width:                    appWin.size

        Rectangle {
            id: mianBackgraund
            height: appWin.size
            width:  appWin.size
            color:  "gray"
            radius: height / 2
        }

        Shape {
            id: trackShape
            height:        appWin.size
            width:         appWin.size
            layer.enabled: true
            layer.samples: 8
            rotation:      180                                // перевернуть обьект по вертикали

            ShapePath {
                id: trackShapePath
                capStyle:    Qt.FlatCap                       // закругленные концы дуги
                fillColor:   "transparent"                    // цвет заполнения внутри круга
                strokeColor: "#505050"                        // цвет внешнего кольца(границы)
                strokeWidth: 15                               // толщина внешней границы

                PathAngleArc {
                    centerX:    appWin.size / 2              // центровка для обоих точек
                    centerY:    appWin.size / 2
                    radiusX:    Math.min(appWin.size, appWin.size) / 2 - Math.max(appWin.trackWidth, appWin.progressWidth) / 2
                    radiusY:    Math.min(appWin.size, appWin.size) / 2 - Math.max(appWin.trackWidth, appWin.progressWidth) / 2
                    startAngle: appWin.startAngle - 90      // на сколько будет повернут обьект(все зависит от начальной точки)
                    sweepAngle: 320 - 40                    // угол актуального пропуска в дуге(будет виден пролет от 40 до 320 градусов)
                }
            }
        }

        // Текст со значением куда повернута стрелка
        Text {
            id: textValue
            z:                1
            anchors.centerIn: mainItem
            text:             value.toFixed(1)
            font.pixelSize:   35
            font.bold:        true
        }

        // В нем мы будем создавать шкалы минутной величины(если мажорные тики это 0, 50, 100 и так далее, то для минорных это 10,20,30)
        Shape
        {
            id: minorTickMarketShape
            height:        appWin.size
            width:         appWin.size
            layer.enabled: true
            layer.samples: 8
//            rotation:      180   // перевернуть обьект по вертикали

            ShapePath
            {
                id: minorTickMarketShapePath
                capStyle:    Qt.FlatCap                        // закругленные концы дуги
                fillColor:   "transparent"                    // цвет заполнения внутри круга
                strokeColor: "blue"                      // цвет внешнего кольца(границы)
                strokeWidth: 10                              // толщина внешней границы

                PathAngleArc
                {
                    id: pathAngleArc
                    centerX:    appWin.size / 2               // центровка для обоих точек
                    centerY:    appWin.size / 2
                    radiusX:    Math.min(appWin.size, appWin.size) / 2 - Math.max(appWin.trackWidth, 50) / 2
                    radiusY:    Math.min(appWin.size, appWin.size) / 2 - Math.max(appWin.trackWidth, 50) / 2
                    startAngle: appWin.startAngle - 90      // на сколько будет повернут обьект(все зависит от начальной точки)
                    sweepAngle: 320 - 40                    // угол актуального пропуска в дуге(будет виден пролет от 40 до 320 градусов)
                }

                PathMultiline {
                    paths:
                    [
                        [Qt.point(minorTickMarketShape.height / 2,     minorTickMarketShape.width / 2),
                         Qt.point(50,       220)],

                        [Qt.point(50.5,     80.12472),
                         Qt.point(50.95,    80.90414)]
                    ]
                }
            }
        }

        Repeater {
            id: tickmarkRepeater
            model:        7
            anchors.fill: parent

            property real p: Math.abs(135  - (-135)) / (tickmarkRepeater.model - 1)

            delegate: Loader {
                id: tickmarkLoader
                x: appWin.width / 2
                y: appWin.height / 2
                sourceComponent: tickmark

                transform: [
                    Rotation {
                        angle: ((-135) + 360 + (index * tickmarkRepeater.p) )
                    },
                    Translate {
                        x: Math.sin(((-135) + 180 + index * tickmarkRepeater.p)
                                    * (Math.PI / 180)) * appWin.majorInsetRadius * -1
                        y: Math.cos(((-135) + 180 + index * tickmarkRepeater.p)
                                    * (Math.PI / 180)) * appWin.majorInsetRadius
                    }
                ]
            }
        }

        // Стрелка
        Rectangle {
            id: needle
            width:        10
            height:       trackShape.height / 2
            color:        "#FFac89"
            radius:       width / 2
            antialiasing: true

            transform: [
                Rotation {
                    angle: needleRotation
                },
                Translate {
                    x: mainItem.width  / 2
                    y: mainItem.height / 2
                }
            ]
        }
    }

    Behavior on value {
        NumberAnimation {
            easing.overshoot: 1.2
            duration:         5000
            easing.type:      Easing.OutBack
        }
    }
}

Записан