Draw an arc/circle sector in QML?

2020-03-15 01:56发布

问题:

I know that it is possible to draw a circle in QML using the following code:

Rectangle {
     width: 150
     height: 150
     anchors.horizontalCenter: parent.horizontalCenter
     anchors.top: parent.top
     color: "#095e7b"
     border.color: "#0a2f4a"
     border.width: 2
     radius: width*0.5
}

My question is: what if I need to draw a sector of a circle. (Pizza Slices) and make each of these slices clickable? Can I do this using QML only?

回答1:

Yes, using Canvas (and Context2D):

import QtQuick 2.3

Rectangle {
    width: 400
    height: 400

    Canvas {
        anchors.fill: parent
        onPaint: {
            var ctx = getContext("2d");
            ctx.reset();

            var centreX = width / 2;
            var centreY = height / 2;

            ctx.beginPath();
            ctx.fillStyle = "black";
            ctx.moveTo(centreX, centreY);
            ctx.arc(centreX, centreY, width / 4, 0, Math.PI * 0.5, false);
            ctx.lineTo(centreX, centreY);
            ctx.fill();

            ctx.beginPath();
            ctx.fillStyle = "red";
            ctx.moveTo(centreX, centreY);
            ctx.arc(centreX, centreY, width / 4, Math.PI * 0.5, Math.PI * 2, false);
            ctx.lineTo(centreX, centreY);
            ctx.fill();
        }
    }
}

I actually took the code for this from this answer, as Qt's Canvas implements the HTML5 Canvas API. This makes it really easy to find examples on the web; just search for "draw pie slice blah html5 canvas", for example.

For the mouse detection, you'll have to brush off your maths skills...

... or just steal the code from here. :)

Note that Canvas only repaints when it's resized, or when requestPaint() is called, so if you want to change the colour of a slice depending on the mouse position, you'll need to call that function to see the colour change.



回答2:

Use charts http://doc.qt.io/QtCharts/qtcharts-qmlmodule.html

import QtQuick 2.0
import QtCharts 2.0

ChartView {
width: 400 
height: 300
theme: ChartView.ChartThemeBrownSand
antialiasing: true

PieSeries {
    id: pieSeries
    PieSlice { label: "eaten"; value: 94.9 }
    PieSlice { label: "not yet eaten"; value: 5.1 }
}
}


回答3:

Draw it using qml, you don't need the canvas. As a guideline I usually go through Qt's examples before deciding on an implementation. The code below can be found in "Shapes" example.

 Shape {
        width: 120
        height: 130
        anchors.bottom: parent.bottom
        anchors.right: parent.right
        //multisample, decide based on your scene settings
        layer.enabled: true
        layer.samples: 4

        ShapePath {
            fillColor: "black"
            strokeColor: "darkBlue"
            strokeWidth: 20
            capStyle: ShapePath.FlatCap

            PathAngleArc {
                centerX: 65; centerY: 95
                radiusX: 45; radiusY: 45
                startAngle: -180
                sweepAngle: 180
            }
        }
    }