setContextProperty()不在qml文件内创建类实例

2024-05-14 20:33:28 发布

您现在位置:Python中文网/ 问答频道 /正文

main.py文件显示一个选项卡小部件。在每个选项卡上,我加载了一个特殊的QML文件,但是为了这个问题,我只考虑一个QML文件和一个单独的选项卡:

import sys, os, math
import numpy as np
from PyQt5 import *

class Tab(QFrame):
    def __init__(self):
        super().__init__()
        self.setGeometry(600, 600, 600, 600)
        self.setWindowTitle("PyQt5 Tab Widget")
       
        vbox = QVBoxLayout()
        tabWidget = QTabWidget()

        tabWidget.addTab(Example01(), "Ex1")
        
        vbox.addWidget(tabWidget)
        self.setLayout(vbox)

class GG(QObject):
    polygonsChanged = pyqtSignal()

    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 = pyqtProperty(
        "QVariant", fget=get_polygons, fset=set_polygons,
        notify=polygonsChanged
    )


class Example01(QWidget):

    def __init__(self):
        super().__init__()
        vbox = QVBoxLayout(self)
        vbox.setContentsMargins(0, 0, 0, 0)


        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 = GG()
        gg.polygons = polygons
        print(gg.polygons)

        ROOT_DIR = os.path.realpath(os.path.dirname(sys.argv[0]))
        # print(ROOT_DIR)

        qml = os.path.join(ROOT_DIR, "QML Files", "Demo01.qml")

        view = QQuickWidget()

        view.setSource(QUrl.fromLocalFile(qml))

        view.rootContext().setContextProperty("gg", gg)

        view.setResizeMode(QQuickWidget.SizeRootObjectToView)
        # widget = QWidget.createWindowContainer(view)
        # vbox.addWidget(widget)

        vbox.addWidget(view)


if __name__ == "__main__":
    App = QApplication(sys.argv)
    tabDialog = Tab()
    tabDialog.show()
    App.exec()

现在是Demo01.qml文件:

import QtQuick 2.14
import QtQuick.Window 2.14
import QtGraphicalEffects 1.0


Rectangle {
    id: rect

        visible: true
        anchors.fill: parent

        LinearGradient {
                anchors.fill: parent
                //setting gradient at 45 degrees
                start: Qt.point(rect.width, 0)
                end: Qt.point(0, rect.height)
                gradient: Gradient {
                    GradientStop { position: 0.0; color: "#ee9d9d" }
                    GradientStop { position: 1.0; color: "#950707" }
                }
            }

        Canvas {
            id: drawingCanvas
            anchors.fill: parent
            onPaint: {
                var ctx = getContext("2d")
                ctx.lineWidth = 5;
                ctx.strokeStyle = "red"
                console.log(gg)
                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
            function onPolygonsChanged(){ drawingCanvas.requestPaint()}
        }
       
    }

问题是没有在qml文件内实例化gg,声称gg对象为空。所以我不会在画布上画任何东西。 我用QQuickWidgetQQuickView试过,结果都是空的。 正如您所看到的,qml页面加载到选项卡窗口上没有任何问题

如果你不使用上述两个元素,如何设置上下文


Tags: 文件importselfviewinitvardefqml
1条回答
网友
1楼 · 发布于 2024-05-14 20:33:28

您的问题有两个错误:

  • 在加载.qml之前,必须设置上下文属性
  • “gg”是一个局部变量,一旦构造函数完成执行,它就会被销毁,因此在qml中它将为null,解决方案是延长生命周期,例如通过使其成为类的属性
class Example01(QWidget):
    def __init__(self):
        super().__init__()
        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)

        self.gg = GG()
        self.gg.polygons = polygons
        ROOT_DIR = os.path.realpath(os.path.dirname(sys.argv[0]))
        qml = os.path.join(ROOT_DIR, "QML Files", "Demo01.qml")

        view = QQuickWidget()
        view.rootContext().setContextProperty("gg", self.gg)
        view.setSource(QUrl.fromLocalFile(qml))
        view.setResizeMode(QQuickWidget.SizeRootObjectToView)

        vbox = QVBoxLayout(self)
        vbox.setContentsMargins(0, 0, 0, 0)
        vbox.addWidget(view)

enter image description here

相关问题 更多 >

    热门问题