Динамически менять цвет полигона - PullRequest
0 голосов
/ 02 июля 2018

Я пытаюсь реализовать функциональность, в которой цвет нарисованного многоугольника может быть динамически изменен. На данный момент у меня есть простое тестовое приложение, в котором я могу нарисовать треугольник и повернуть его. Затем я добавил 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()
    }
}

Графический интерфейс до изменения цвета:

enter image description here

Графический интерфейс после изменения цвета:

enter image description here

После короткого нажатия на кнопку, в конце концов, треугольник появляется в неправильном месте:

enter image description here

1 Ответ

0 голосов
/ 02 июля 2018

Цвет изменяется, но в повернутом треугольнике, поскольку операции вращения и перемещения сохраняются, поэтому после определенного количества нажатий вы видите половину треугольника правильного цвета. Решение состоит в том, чтобы сохранить состояние до преобразований и восстановить его после рисования с помощью 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

...