在QML中绘制弧/圆扇区?

时间:2014-09-25 17:39:19

标签: qt qml draw geometry sector

我知道可以使用以下代码在QML中绘制一个圆圈:

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
}

我的问题是:如果我需要画一个圆圈的扇区怎么办? (披萨切片)并使这些切片中的每一个都可点击?我可以只使用QML吗?

3 个答案:

答案 0 :(得分:9)

是的,使用Canvas(和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();
        }
    }
}

我实际上从this回答了这个代码,因为Qt的Canvas实现了HTML5 Canvas API。这使得在网络上找到示例变得非常容易;例如,只需搜索“draw pie slice blah html5 canvas”。

对于鼠标检测,你将不得不刷掉你的数学技能......

...或者只是从here窃取代码。 :)

请注意,Canvas仅在调整大小时或重新调整requestPaint()时重新绘制,因此如果要根据鼠标位置更改切片的颜色,则需要调用该函数以查看颜色变化。

答案 1 :(得分:2)

使用图表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 }
}
}

答案 2 :(得分:1)

由于问题在于绘制“比萨饼切片”并使它们每个都可点击,所以一个重要的细节是将点击次数映射到正确的细分(也就是正确的“比萨饼切片”)。

先前的答案似乎都没有包含任何onClicked处理,因此我提供了另一种可能性。 (所有先前的答案也是有效的,只是它们并不能立即明确指出在何处拦截点击。)

我有一个类似的案例,我需要在45度对角线上切一个矩形,并检测点击是否落在对角线之上或之下。

很幸运,事实证明QML允许您:

  • 创建网格
  • transform: Rotation应用于该网格
  • ...,然后自动使您的点击“正常”
    • (意思是:按需单击45度旋转的矩形地图)

该演示代码渲染如下所示的旋转网格,并输出(通过console.log)您单击的颜色:

rotated grid of QML rectangles

以下内容已在使用Qt 5.14的Ubuntu上进行了测试

import QtGraphicalEffects 1.12
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Controls.Universal 2.2
import QtQuick.Layouts 1.14

Item {
  height: 1000
  width: 2000

  GridLayout {
    id: grid
    columnSpacing: 0 // the default is non-zero!
    rowSpacing: 0
    anchors.centerIn: parent
    rows: 2
    columns: 2

    Rectangle {
      height: 200
      width: 200
      color: 'red'
      MouseArea {
        anchors.fill: parent
        onClicked: {
          console.log('red')
        }
      }
    }
    Rectangle {
      height: 200
      width: 200
      color: 'yellow'
      MouseArea {
        anchors.fill: parent
        onClicked: {
          console.log('yellow')
        }
      }
    }
    Rectangle {
      height: 200
      width: 200
      color: 'green'
      MouseArea {
        anchors.fill: parent
        onClicked: {
          console.log('green')
        }
      }
    }
    Rectangle {
      height: 200
      width: 200
      color: 'blue'
      MouseArea {
        anchors.fill: parent
        onClicked: {
          console.log('blue')
        }
      }
    }
    transform: Rotation {
      origin.x: grid.width * 0.5
      origin.y: grid.height * 0.5
      axis {
        x: 0
        y: 0
        z: 1
      }
      angle: 45
    }
  }
}