访问作为信号发送到 QML 的 Python 个字典条目

Access Python dictionary entries sent as signal to QML

首先,我知道有人发布了类似的问题 。但是,我已经尝试过此解决方案,但没有成功。这是我的代码的最小可验证示例:

from PySide2.QtGui import QGuiApplication
from PySide2.QtQml import QQmlApplicationEngine
from PySide2.QtCore import QObject, Signal, Slot
 
 
class Dictionary(QObject):
    def __init__(self):
        QObject.__init__(self)
        self.dictionary = {1: "Word1", 2: "Word2"}

    sendDict = Signal(dict)
    
    @Slot(bool)
    def s_dict(self, arg1):
        self.sendDict.emit(self.dictionary)

if __name__ == "__main__":
    import sys
 
    app = QGuiApplication(sys.argv)
    engine = QQmlApplicationEngine()
    dictionary = Dictionary()
    engine.rootContext().setContextProperty("dictionary", dictionary)
    engine.load("main.qml")
 
    engine.quit.connect(app.quit)
    sys.exit(app.exec_()) 

这是 QML 文件:

import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.2
 
ApplicationWindow {
    visible: true
    width: 640
    height: 240
    title: qsTr("Minimum Verifiable Example")
    color: "whitesmoke"
 
    GridLayout {
        anchors.top: parent.top
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.margins: 9
 
        columns: 4
        rows: 4
        rowSpacing: 10
        columnSpacing: 10
 
        Button {
            height: 40
            Layout.fillWidth: true
            text: qsTr("Emit dictionary!")
 
            Layout.columnSpan: 2
 
            onClicked: {
                dictionary.s_dict(true)
            }
        }
    }

 
    Connections {
        target: dictionary
        function onSendDict(arg1) {console.log(arg1)}
    }
}

简单地说,我想用console.log打印这本字典的元素,但我得到的只是:qml: QVariant(PySide::PyObjectWrapper, )。我也试过索引它,但无济于事(它 returns 未定义)。

感谢您的宝贵时间!

这是解决两个问题的工作代码:

  1. 信号需要使用“QVariantMap”进行规范,以便 pyside 将其作为对象正确编组到 QML 中。

  2. Javascript 中的对象键始终是字符串,因此编组似乎正在跳过您的整数键。请改用字符串。

from PySide2.QtGui import QGuiApplication
from PySide2.QtQml import QQmlApplicationEngine
from PySide2.QtCore import QObject, Signal, Slot
 
 
class Dictionary(QObject):
    def __init__(self):
        QObject.__init__(self)
        self.dictionary = {"1": "Word1", "2": "Word2"}

    sendDict = Signal("QVariantMap")
    
    @Slot(bool)
    def s_dict(self, arg1):
        self.sendDict.emit(self.dictionary)

if __name__ == "__main__":
    import sys
 
    app = QGuiApplication(sys.argv)
    engine = QQmlApplicationEngine()
    dictionary = Dictionary()
    engine.rootContext().setContextProperty("dictionary", dictionary)
    engine.load("main.qml")
 
    engine.quit.connect(app.quit)
    sys.exit(app.exec_()) 

import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.2
 
ApplicationWindow {
    visible: true
    width: 640
    height: 240
    title: qsTr("Minimum Verifiable Example")
    color: "whitesmoke"
 
    GridLayout {
        anchors.top: parent.top
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.margins: 9
 
        columns: 4
        rows: 4
        rowSpacing: 10
        columnSpacing: 10
 
        Button {
            height: 40
            Layout.fillWidth: true
            text: qsTr("Emit dictionary!")
 
            Layout.columnSpan: 2
 
            onClicked: {
                dictionary.s_dict(true)
            }
        }
    }

 
    Connections {
        target: dictionary
        function onSendDict(arg1) {
            console.log(arg1);
            console.log(JSON.stringify(arg1, null, 4));
        }
    }
}

输出:

qml: [object Object]
qml: {
    "1": "Word1",
    "2": "Word2"
}

您还可以使用 JSON 并将 Python 数据结构编码为字符串,将字符串传递给 QML 并使用 Javascript 中的 JSON.parse 对其进行解码。这可能适用于更复杂的数据结构。