动态更改多边形颜色

时间:2018-07-02 06:02:09

标签: qt canvas qml qt5

我正在尝试实现一种功能,可以动态更改绘制的多边形的颜色。目前,我有一个简单的测试应用程序,可以绘制三角形并旋转它。然后,我添加了2个用于更改所有对象颜色的按钮。

矩形和文本颜色可以正确更改,但绘制的多边形不能更改。随机单击颜色更改按钮后,最终会绘制一个新的多边形,但位置不正确。我真的不知道可能是什么问题。

代码如下:

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.2

Window {
    visible: true
    width: 480
    height: 800

    Ucolors
    {
        id: colDay

        canvas: "#eaedf1"
        text: "#0e0e12"
        spiderBckgrnd: "#f7fbff"
        spiderLines: "#C8CBD0"
    }

    Ucolors
    {
        id: colNight

        canvas: "#22212c"
        text: "#ffffff"
        spiderBckgrnd: "#0e0e12"
        spiderLines: "#3C3C3F"
    }

    property var colGlob: colDay

    Rectangle
    {
        id: rectMain
        anchors.centerIn: parent
        width: parent.width
        height: parent.height
        color: colGlob.canvas

        Text
        {
            anchors.right: parent.right
            color: colGlob.text
            text: qsTr("text")
        }

        Button
        {
            id: btn1
            anchors.left: parent.left
            text: "button1"

            onClicked:
            {
                colGlob = colNight;
            }
        }

        Button
        {
            id: btn2
            anchors.left: btn1.right
            text: "button2"

            onClicked:
            {
                colGlob = colDay;
            }
        }

        Rectangle
        {
            id: rectTemp
            anchors.centerIn: parent
            width: 374
            height: 432
            //color: "transparent"
            color: "red"

            Utriangle
            {
                trbase: 183
                rotAngle: 30
                fillColor: colGlob.spiderBckgrnd
                strokeColor: colGlob.spiderLines
                anchors.centerIn: parent
            }
        }
    }
}

Ucolors.qml

import QtQuick 2.9

/**
 * @brief   Holds the color parameters of the whole UI
 *
 */
Item
{
    property var canvas
    property var text
    property var spiderBckgrnd
    property var spiderLines
}

Utriangle.qml

import QtQuick 2.9

/**
 * @brief   This object draws an equilateral triangle in the middle of the
 *          parent object. The triangle at \p rotAngle 0 is being drawn
            starting from one of the corners facing down.

            \p hFactor of 1 will draw a triangle with the height that coresponds
            to the set \p base. Fractional values will make the triangle height
            shorter accordingly.
 *
 */
Canvas
{
    anchors.fill: parent

    // set properties with default values
    property real hFactor: 1    // height factor
    property int trbase: 50
    property color strokeColor: "black"
    property color fillColor: "yellow"
    property int lineWidth: 1
    property real alpha: 1
    property real rotAngle: 0

    onStrokeColorChanged: requestPaint();
    onFillColorChanged: requestPaint();
    onLineWidthChanged: requestPaint();

    onPaint:
    {
        var ctx = getContext("2d") // get context to draw with
        ctx.lineWidth = lineWidth
        ctx.strokeStyle = strokeColor
        ctx.fillStyle = fillColor
        ctx.globalAlpha = alpha

        ctx.beginPath()
        ctx.translate(parent.width / 2, parent.height / 2)
        ctx.rotate((Math.PI / 180) * rotAngle)
        ctx.moveTo(0, 0)

        // drawing part, first calculate height using Pythagoras equation
        var trheight = Math.sqrt(Math.pow(trbase, 2) - Math.pow(trbase / 2, 2))
        trheight = trheight * Math.abs(hFactor)
        var hfBase = trbase * Math.abs(hFactor)
        ctx.lineTo(hfBase / -2, trheight) // left arm
        ctx.lineTo(hfBase / 2, trheight) // right arm

        ctx.closePath(); // base drawn aoutomatically
        ctx.fill()
        ctx.stroke()
    }
}

更改颜色之前的gui:

enter image description here

更改颜色后的gui:

enter image description here

单击按钮一段时间后,最终三角形显示在错误的位置:

enter image description here

1 个答案:

答案 0 :(得分:2)

由于保持了旋转和平移操作,因此更改了颜色,但颜色变为旋转的三角形,因此,在单击一定量后,您会看到正确颜色的三角形的一半。解决方案是在转换之前保存状态,并在使用save()和restore()绘制后恢复状态。

onPaint:
{
    var ctx = getContext("2d") // get context to draw with
    ctx.lineWidth = lineWidth
    ctx.strokeStyle = strokeColor
    ctx.fillStyle = fillColor
    ctx.globalAlpha = alpha

    ctx.save(); // <---

    ctx.beginPath()
    ctx.translate(parent.width / 2, parent.height / 2)
    ctx.rotate((Math.PI / 180) * rotAngle)
    ctx.moveTo(0, 0)

    // drawing part, first calculate height using Pythagoras equation
    var trheight = Math.sqrt(Math.pow(trbase, 2) - Math.pow(trbase / 2, 2))
    trheight = trheight * Math.abs(hFactor)
    var hfBase = trbase * Math.abs(hFactor)
    ctx.lineTo(hfBase / -2, trheight) // left arm
    ctx.lineTo(hfBase / 2, trheight) // right arm

    ctx.closePath(); // base drawn aoutomatically

    ctx.fill()
    ctx.stroke()

    ctx.restore(); // <---
}

enter image description here

enter image description here