Полигон на холсте (QML) из массива Numpy в Python - PullRequest
0 голосов
/ 05 ноября 2019

Я должен напечатать полигоны на холсте, но я не знаю, как это сделать. Вершины многоугольников запоминаются в собственных .__ многоугольниках, которые являются массивом, измененным другой функцией. Я пробовал пару методов, но ничего. Я прокомментировал код для объяснения каждой функции.

GG.py

    class GG(QObject):

        def __init__(self, cameraIntrinsics, floorExtrinsics):
            QObject.__init__(self)
            self.__polygons = np.array

        def modArray(self):

            #function that elaborate 
            #polygon=[[a,b],[c,d],[e,f],[g,h]], where each [x,y]         
            #contains the coordinate of a vertice of the polygon, 
            #are the vertices of the polygon,
            #and add the latter to
            #self.__polygons, that is an array of poligons


        def drawPol(self):
            #function that draw a polygon on canvas


    if __name__ == '__main__':
        app = QGuiApplication(sys.argv)
        gg = GG()
        engine = QQmlApplicationEngine()
        engine.rootContext().setContextProperty("gg", gg)

        currentPath = os.path.abspath(os.path.dirname(__file__))
        qmlPath = os.path.join(currentPath, 'try.qml')
        engine.load(QUrl.fromLocalFile(qmlPath))  

        if not engine.rootObjects():
            sys.exit(-1)   

        sys.exit(app.exec_())

try.qml

    import QtMultimedia 5.0
    import QtQuick 2.12
    import QtQuick.Controls 2.12
    import QtQuick.Controls.Material 2.12
    import QtQuick.Window 2.12
    import QtQml 2.11
    import Qt.labs.folderlistmodel 2.1
    import QtQuick.Dialogs 1.3
    import QtQml.StateMachine 1.0 as DSM
    import QtCharts 2.13

    ApplicationWindow {
        title: "window"
        visible: true
        id: window
        width:940
        height:510

        Rectangle {
            id: imgVisualizer
            anchors.left: window.left; anchors.top: window.top
            color: "transparent"
            width:610
            height:510
            Image {
                id: img
                anchors.fill: parent
                source: "file:///input.png"
            }

            Canvas {
                id: drawingCanvas
                anchors.fill: parent

                onPaint: {
                    var ctx = getContext("2d")

                    ctx.setTransform()
                    ctx.lineWidth = 5;
                    ctx.strokeStyle = "red"

                    //print each edge of the polygon

                    ctx.beginPath()
                    ctx.moveTo(a, b)
                    ctx.lineTo(c, d)
                    ctx.lineTo(e, f)
                    ctx.lineTo(g, h)
                    ctx.stroke()
                }
          }
      }

1 Ответ

0 голосов
/ 05 ноября 2019

У вас должны быть следующие соображения:

  • Если вы собираетесь взаимодействовать с QML, рекомендуется использовать классы, изначально принятые QML, например, используя непосредственно массив numpyне подходит, вместо этого вы должны преобразовать его, например, в массив QPointF.

  • Рисование должно выполняться не в python, а в QML, и для этого вы должны создать свойство, которое уведомляет вас. изменения, например, создать свойство, которое предоставляет список.

Учитывая вышеизложенное, решение:

import os
import sys

import numpy as np

from PySide2.QtCore import Property, QObject, QPointF, QUrl, Signal
from PySide2.QtGui import QGuiApplication
from PySide2.QtQml import QQmlApplicationEngine


class GG(QObject):
    polygonsChanged = Signal()

    def __init__(self, parent=None):
        super().__init__(parent)
        self._polygons = []

    def get_polygons(self):
        return self._polygons

    def set_polygons(self, polygons):
        self._polygons = polygons
        self.polygonsChanged.emit()

    polygons = Property(
        "QVariantList", fget=get_polygons, fset=set_polygons, notify=polygonsChanged
    )


if __name__ == "__main__":
    app = QGuiApplication(sys.argv)
    gg = GG()

    numpy_arrays = np.array(
        [[[100, 100], [150, 200], [50, 300]], [[50, 60], [160, 10], [400, 0]]]
    )

    polygons = []
    for ps in numpy_arrays:
        polygon = []
        for p in ps:
            e = QPointF(*p)
            polygon.append(e)
        polygons.append(polygon)

    gg.polygons = polygons
    engine = QQmlApplicationEngine()
    engine.rootContext().setContextProperty("gg", gg)

    currentPath = os.path.abspath(os.path.dirname(__file__))
    qmlPath = os.path.join(currentPath, "try.qml")
    engine.load(QUrl.fromLocalFile(qmlPath))

    if not engine.rootObjects():
        sys.exit(-1)

    sys.exit(app.exec_())
import QtQuick 2.12
import QtQuick.Controls 2.12

ApplicationWindow {
    id: window
    title: "window"
    visible: true
    width:940
    height:510

    Canvas {
        id: drawingCanvas
        anchors.fill: parent
        onPaint: {
            var ctx = getContext("2d")
            ctx.lineWidth = 5;
            ctx.strokeStyle = "red"
            for(var i in gg.polygons){
                var polygon = gg.polygons[i]
                ctx.beginPath()
                for(var j in polygon){
                    var p = polygon[j]
                    if(j == 0)
                        ctx.moveTo(p.x, p.y)
                    else
                        ctx.lineTo(p.x, p.y)
                }
                ctx.closePath()
                ctx.stroke()
            }
        }
    }
    Connections{
        target: gg
        onPolygonsChanged: drawingCanvas.requestPaint()
    }
}
...