如何优化我的代码?并使endangle的角度与光标圆相等

How can I optimize my code? And to equate the angle of the endangle with the cursor circle

首先我要优化这段代码, 其次,Endangle 不能正常工作,我希望 canvas 的角度与光标圆的角度相同。 image

我在这个属性的目标是我想自定义对象,并且在设计项目时准备好对象,我想编写一个用于HMI的程序,如Dopsoft,我想要对象准备好。

Dial.qml

import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Shapes 1.12
import QtQuick.Controls.Styles 1.4
import QtGraphicalEffects 1.0
import QtQml 2.12
import QtQuick.Layouts 1.12

Item {
    id: dial_item

    property string dial_fontStyle: "Calibri"
    property real dial_x: 400
    property real dial_y: 200
    property real dial_width: 200
    property real dial_height: dial_width
    property real dial_value: 10
    property real dial_textSize: 55
    property string dial_textColor: "white"//"#29b6f6"
    property string dial_backColor: "orange"
    property bool dial_textBold: false
    property string dial_borderColorPress: "gray"
    property string dial_borderColorNotPress: "yellow"
    property real dial_borderWidth: 2
    property string dial_strokeColor: "#29b6f6"
    property real dial_strokeWidth: 10
    property real dial_widthCursor: 16
    property real dial_heightCursor: dial_widthCursor
    property string dial_cursorColorPress: "blue"
    property string dial_cursorColorNotPress: "#21be2b"
    property real dial_cursorRadius: 8

    property real dial_shadowGlowRadius: 2
    property real dial_shadowSpread: 0.8
    property string dial_shadowColor: "black"
    property real dial_shadowRadius: dial_width / 2


    // shdow for delay button
    RectangularGlow {
        id: effect
        width: dial_width
        height: dial_height
        x: dial_x
        y: dial_y
        glowRadius: dial_shadowGlowRadius
        spread: dial_shadowSpread
        color: dial_shadowColor
        cornerRadius: dial_shadowRadius
    }


    FontLoader { id: fontStyle; name: dial_fontStyle }

    // @disable-check M129
    Dial {
        id: dial
        x:dial_x
        y: dial_y
        width: dial_width
        height: dial_height

        Text {
            id: txt
            text: qsTr(dial_value + "%")
            anchors.centerIn: parent
            font.family: fontStyle.name
            font.pixelSize: dial_textSize
            font.bold: dial_textBold
            color: dial_textColor
        }

        background: Rectangle {
            id: rect
            x: dial.width / 2 - width / 2
            y: dial.height / 2 - height / 2
            width: Math.max(64, Math.min(dial.width, dial.height))
            height: width
            color: dial_backColor
            radius: width / 2
            border.color: dial.pressed ? dial_borderColorPress : dial_borderColorNotPress
            border.width: dial_borderWidth
            opacity: dial.enabled ? 1 : 0.3
            Canvas {
                id: canvas
                anchors.fill: parent

                Connections {
                    target: dial
                    onAngleChanged: canvas.requestPaint()
                }

                onPaint: {
                    var ctx = getContext("2d")
                    ctx.clearRect(0, 0, width, height)
                    ctx.strokeStyle = dial_strokeColor
                    ctx.lineWidth = dial_strokeWidth
                    ctx.beginPath()
                    var startAngle = Math.PI / 5 * 3.6
                    var endAngle = startAngle + ((280 * (Math.PI/180)) * (dial.angle / 0.87))
                    if (endAngle > 0.87) endAngle = 0.87
                    ctx.arc(width / 2, height / 2, width / 2 - ctx.lineWidth / 2 - 2, startAngle, endAngle)
                    ctx.stroke()
                }
            }
        }
        handle: Rectangle {
            id: handleItem
            x: dial.background.x + dial.background.width / 2 - width / 2
            y: dial.background.y + dial.background.height / 2 - height / 2
            width: dial_widthCursor
            height: dial_heightCursor
            color: dial.pressed ? dial_cursorColorPress : dial_cursorColorNotPress
            radius: dial_cursorRadius
            antialiasing: true
            opacity: dial.enabled ? 1 : 0.3

            transform: [
                Translate {
                    y: -Math.min(dial.background.width, dial.background.height) * 0.4 + handleItem.height / 2
                },
                Rotation {
                    angle: dial.angle
                    origin.x: handleItem.width / 2
                    origin.y: handleItem.height / 2
                }
            ]
        }
    }
}

欢迎使用 Whosebug MReza!

你的代码有几个问题。

  1. 我觉得命名约定很奇怪。在 Dial.
  2. 中定义属性时,您实际上并不需要 dial_ 前缀
  3. 使用 alias 属性是个好主意。它们的存在是为了解决问题。所以我建议您从 Qt 文档中 read more about it
  4. 您并不需要 Item 类型的根项目来添加阴影效果。由于您已经为 Dial 定义了自定义背景,因此您可以将 RectangularGlow 效果放入背景项中。现在,生成的组件将更像原始 Dial 组件,用户将可以直接访问原始 Dial 组件的属性、信号和方法。
  5. Dial 组件有一个 angle 属性。这意味着您不需要对 endAngle 进行任何计算。不管怎样,0度数的定义是不同的是表盘和Canvas。他们有 90 度的差异,应该在我们的计算中扣除。
  6. FontLoader 不打算用于组件设计。

结果可能如下所示。我没有花太多时间进一步优化它。我很确定您需要一些时间来分析所有更改。但是值得。

import QtQuick 2.12
import QtQuick.Controls 2.12
import QtGraphicalEffects 1.0
import QtQml 2.12


Dial {
    id: dial

    implicitWidth: 200
    implicitHeight: 200

    property color strokeColor: "#29b6f6"
    property real strokeWidth: 10

    property real cursorWidth: 16
    property real cursorHeight: 16
    property real cursorRadius: 16

    property color cursorPressedColor: "gray"
    property color cursorReleasedColor: "yellow"

    property alias fontFamily: txt.font.family
    property alias fontPixelSize: txt.font.pixelSize
    property alias fontBold : txt.font.bold
    property alias textColor : txt.color
    property alias backColor : rect.color
    property alias borderWidth: rect.border.width

    property real shadowRadius: effect.glowRadius
    property real shadowSpread: effect.spread
    property string shadowColor: effect.color


    Text {
        id: txt
        text: Math.round(dial.value * 100.0) + "%"
        anchors.centerIn: parent
        font.family: 'Calibri'
        font.pixelSize: dial.width / 4
        font.bold: false
        color: "white"
    }

    background: Item{

        RectangularGlow {
            id: effect
            anchors.fill: parent
            glowRadius: 2
            spread: 0.8
            color: "black"
            cornerRadius: dial.width
        }
        Rectangle {
            id: rect
            x: dial.width / 2 - width / 2
            y: dial.height / 2 - height / 2
            width: Math.max(64, Math.min(dial.width, dial.height))
            height: width
            color: "orange"
            radius: width / 2
            border.color: dial.pressed ? cursorPressedColor : cursorReleasedColor
            border.width: 2
            opacity: dial.enabled ? 1 : 0.3
            Canvas {
                id: canvas
                anchors.fill: parent

                Connections {
                    target: dial
                    function onAngleChanged(){
                        canvas.requestPaint()
                    }
                }

                onPaint: {
                    var ctx = getContext("2d")
                    ctx.clearRect(0, 0, width, height)
                    ctx.strokeStyle = strokeColor
                    ctx.lineWidth = strokeWidth
                    ctx.beginPath()
                    var startAngle = (-140 - 90) * (Math.PI/180.0)
                    var endAngle = (dial.angle - 90)  * (Math.PI/180.0)
                    if (endAngle > 0.87) endAngle = 0.87
                    ctx.arc(width / 2, height / 2, width / 2 - ctx.lineWidth / 2 - 2, startAngle, endAngle)
                    ctx.stroke()
                }
            }
        }


    }
    handle: Rectangle {
        id: handleItem
        x: dial.background.x + dial.background.width / 2 - width / 2
        y: dial.background.y + dial.background.height / 2 - height / 2
        width: cursorWidth
        height: cursorHeight
        color: dial.pressed ? cursorPressedColor : cursorReleasedColor
        radius: cursorRadius
        antialiasing: true
        opacity: dial.enabled ? 1 : 0.3

        transform: [
            Translate {
                y: -Math.min(dial.background.width, dial.background.height) * 0.4 + handleItem.height / 2
            },
            Rotation {
                angle: dial.angle
                origin.x: handleItem.width / 2
                origin.y: handleItem.height / 2
            }
        ]
    }

}