python - 来自 Python 中的 Numpy 数组的 Canvas 上的多边形 (QML)

标签 python numpy qml pyside2

我必须在 Canvas 上打印多边形,但我不知道如何做到这一点。多边形的顶点存储在 self.__polygons 中,它是一个由另一个函数修改的 numpy 数组。 我尝试了几种方法,但没有任何效果。我已经注释了代码来解释每个函数。

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_())

尝试.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()
                }
          }
      }

最佳答案

您必须考虑以下因素:

  • 如果您要与 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()
    }
}

关于python - 来自 Python 中的 Numpy 数组的 Canvas 上的多边形 (QML),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58712900/

相关文章:

python - 如何防止用户通过 CTRL + Z 停止脚本?

python - 绘制目录中的所有数据文件

python - 屏蔽二维数组替换值操作在 numpy 中不起作用

python - PySide2 中 QScxmlStateMachine.connectToEvent 的奇怪行为

c++ - 类似 QML 的方法或编程语言?

python - 在 PyQt QAction 菜单中右对齐 QKeySequence

python - 向我的答题游戏添加粒子效果

Python 天增量 : Remove time from days output in dataframe and convert column to float

python - 根据一段时间内的平均值对面板数据框中的项目进行分类

c++ - QML 连接在新插入的行中不起作用?