Начертайте дъга/окръжен сектор в 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
}

Въпросът ми е: какво ще стане, ако трябва да начертая сектор от окръжност. (Pizza Slices) и да направите всяко от тези парчета да може да се кликва? Мога ли да направя това само с QML?


person RafaelTSCS    schedule 25.09.2014    source източник


Отговори (4)


Да, използвайки 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();
        }
    }
}

Всъщност взех кода за това от това отговор, тъй като Canvas на Qt имплементира HTML5 Canvas API. Това прави много лесно намирането на примери в мрежата; просто потърсете "draw pie slice blah html5 canvas", например.

За откриването на мишката ще трябва да изчистите математическите си умения...

... или просто откраднете кода от тук. :)

Имайте предвид, че Canvas прерисува само когато е преоразмерен или когато requestPaint() се извиква, така че ако искате да промените цвета на парче в зависимост от позицията на мишката, ще трябва да извикате тази функция, за да видите промяната на цвета.

person Mitch    schedule 25.09.2014

Начертайте го с помощта на 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
        }
    }
}
person neagoegab    schedule 20.01.2020

Използвайте диаграми 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 }
}
}
person Dany19    schedule 25.04.2016
comment
Сигнал за лицензиране! Тези от нас, които пишат търговски код, трябва да са наясно: за разлика от повечето Qt, QtCharts не е лицензиран съгласно LGPL. Ако вашият продукт е със затворен код, ще ви трябва търговски Qt лиценз, за ​​да използвате QtCharts. - person pestophagous; 29.04.2020

Тъй като въпросът беше за изчертаване на „филии пица“ и правене на всяко от тях с възможност за щракване, важен детайл е картографирането на щракванията към десния сегмент (известен още като десния „филий пица“).

Нито един от предишните отговори изглежда не съдържа onClicked обработка, така че предлагам още една възможност. (Всички предишни отговори също са валидни, те просто не изясняват веднага къде да се прихванат кликванията.)

Имах подобен случай, при който трябваше да нарежа правоъгълник по диагонал от 45 градуса и да открия дали щракванията попадат над или под диагоналната линия.

За щастие се оказва, че QML ви позволява да:

  • създайте решетка
  • приложете transform: Rotation към тази мрежа
  • ... and then automatically your clicks "just work"
    • (meaning: clicking on a 45-degree rotated rectangle maps as you would wish)

Демонстрационният код изобразява завъртяна мрежа като следната и извежда (чрез 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
    }
  }
}

person pestophagous    schedule 28.04.2020