繁体   English   中英

在 QML 中绘制弧/圆扇区?

[英]Draw an arc/circle sector in QML?

我知道可以使用以下代码在 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 来做到这一点吗?

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

我实际上从这个答案中获取了代码,因为 Qt 的 Canvas 实现了 HTML5 Canvas API。 这使得在网络上找到示例变得非常容易; 例如,只需搜索“绘制饼图切片等等 html5 画布”。

对于鼠标检测,你必须刷掉你的数学技能......

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

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

使用qml绘制它,您不需要画布。 作为指导方针,我通常在决定实现之前先浏览 Qt 的示例。 下面的代码可以在“形状”示例中找到。

import QtQuick 2.11
import QtQuick.Shapes 1.15

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
        }
    }
}

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

由于问题是关于绘制“披萨片”并使它们中的每一个都可点击,因此一个重要的细节是将点击映射到正确的部分(也就是正确的“披萨片”)。

先前的答案似乎都没有包含任何onClicked处理,所以我提供了另一种可能性。 (所有先前的答案也是有效的,他们只是没有立即清楚在哪里拦截点击。)

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

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

  • 创建网格
  • 应用transform: Rotation到那个网格
  • ...然后你的点击会自动“正常工作”
    • (意思是:按你的意愿点击一个 45 度旋转的矩形地图)

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

QML 矩形的旋转网格

以下已在 Ubuntu 上使用 Qt 5.14 进行测试

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
    }
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM