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 } } }
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 } ] } }
import QtQuickimport QtQuick.Controlsimport QtQuick.ShapesItem { 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 } }}