【问题标题】:How can I send a python dictionary to a QML interface with a Signal?如何使用 Signal 将 python 字典发送到 QML 接口?
【发布时间】:2019-02-19 14:21:28
【问题描述】:

我想发送字典,包含我需要用于动态创建 qml 对象的数据,从 PySide2 类到 QML 接口,因为我需要响应某些事件,所以我需要使用信号和槽.

由于我刚开始使用 QML 和 python,我尝试创建一个简单的项目来玩玩(从代码中可以看到)

QML:

import QtQuick 2.10
import QtQuick.Controls 2.2
import QtQuick.Window 2.2
import QtQuick.Controls.Material 2.3
import QtQuick.Layouts 1.0

ApplicationWindow {
    id: mainWindow
    width:640
    height: 480
    title: qsTr("Simple ui")
    visible: true
    locale:locale
    Rectangle {
        id: appWindow
        objectName: "splasso"
        anchors.fill: parent
        color: "yellow"
        Material.accent: Material.DeepPurple
        Material.primary: Material.Cyan
        Component.onCompleted: function(){
            TestVar.theSignal.connect(catchAnswer);
            testList.append(stuff1);
            testList.append(stuff2);
            testList.append(stuff3);
            testCombo.currentIndex = 0;
            //Just a pointless test print
            console.log(JSON.stringify(stuff1));
        }
        function catchAnswer(answer){
            console.log(JSON.stringify(answer));
        }

        ComboBox{
            id: testCombo
            anchors.centerIn: parent
            width: parent.width
            onCurrentIndexChanged: function(){
                TestVar.catchInt(currentIndex);
            }

            model: ListModel{
                id: testList
            }
        }
    }
}

Python 3:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import os
from time import sleep

from PySide2.QtCore import Qt, QObject, Signal, Slot, Property, QThread
from PySide2.QtWidgets import QApplication    
from PySide2.QtQml import QQmlApplicationEngine

class Test1(QObject):
    theSignal = Signal(dict)
    def __init__(self):
        QObject.__init__(self)

    @Slot(int)
    def catchInt(self,caught):
        print("Caught: {0}".format(caught))
        testDict = {"myAnswer":caught}
        self.theSignal.emit(testDict)


if __name__ == "__main__":
    os.environ["QT_QUICK_CONTROLS_STYLE"] = "Material"
    app = QApplication(sys.argv)
    engine = QQmlApplicationEngine()
    stuff1 = {"text":"Trying"}
    stuff2 = {"text":"To send"}
    stuff3 = {"text":"Dict"}
    ctx = engine.rootContext()
    ctxVar = Test1()
    ctx.setContextProperty("stuff1", stuff1)
    ctx.setContextProperty("stuff2", stuff2)
    ctx.setContextProperty("stuff3", stuff3)
    ctx.setContextProperty("TestVar",ctxVar)
    engine.load('main.qml')
    if not engine.rootObjects():
        sys.exit(-1)

    sys.exit(app.exec_())

我预期的输出(使用“python3 Test_dict_1.py”启动脚本)是:

Caught: 1
qml: {"myAnswer": 1}
Caught: 2
qml: {"myAnswer": 2}
Caught: 1
qml: {"myAnswer": 1}
...etc...

我得到的是:

Caught: 1
qml: undefined.
Caught: 2
qml: undefined.
Caught: 1
qml: undefined.
...etc...

你能告诉我我做错了什么吗?是不是代码有错误或者这件事不能做?

【问题讨论】:

    标签: python qml pyside2 qt-signals qt-slot


    【解决方案1】:

    您必须在信号中使用的签名是QVariant

    class Test1(QObject):
        theSignal = Signal('QVariant')
    
        @Slot(int)
        def catchInt(self,caught):
            print("Caught: {0}".format(caught))
            testDict = {"myAnswer":caught}
            self.theSignal.emit(testDict)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-17
      • 2010-12-06
      • 2021-12-21
      相关资源
      最近更新 更多