<div dir="ltr"><div>Sending basic javascript objects (ie: anything expressible with simple json) down to PyQt works fantastically well with the use of <font face="monospace, monospace">QJSValue.toVariant()</font>, but I'm having a hard time figuring out how to do the reverse.</div><div><br></div><div>What is the correct way to send arbitrarily nested, json-expressible, objects from PyQt up to QML?</div><div><br></div><div>Below is a small example that demonstrates both aspects.  Push the button and you can send an arbitrary javascript/json object down to python.  It will translate to python perfectly.  The example then tries to send it back to QML in a signal argument, but the result isn't quite right.</div><div><br></div><div>Here's the console output for the unmodified example (after button push):</div><div><font color="#674ea7"><br></font></div><div><div><font face="monospace, monospace" color="#674ea7">Python received: [{'foo': 'bar', 'baz': 1}, [1, 2, 3]]</font></div><div><font face="monospace, monospace" color="#674ea7">Emitting signal...</font></div><div><font face="monospace, monospace" color="#674ea7">qml: QML received: [object Object],1,2,3</font></div></div><div><br></div><div>Ideally, QML should receive the same thing!</div><div><br></div><div>I have tried some variations of QJSValue and QVariant with no success.  What is the correct way to do this?</div><div><br></div><div>Here is the complete example:</div><div><br></div><div><div><font color="#674ea7" face="monospace, monospace">#!/usr/bin/env python</font></div><div><font color="#674ea7" face="monospace, monospace">import sys</font></div><div><span style="color:rgb(103,78,167);font-family:monospace,monospace">from PyQt5 import QtCore, QtQml, QtQml, QtWidgets</span><br></div><div><font color="#674ea7" face="monospace, monospace"><br></font></div><div><font color="#674ea7" face="monospace, monospace">QML = '''</font></div><div><font color="#674ea7" face="monospace, monospace">import QtQuick 2.5</font></div><div><font color="#674ea7" face="monospace, monospace">import QtQuick.Window 2.2</font></div><div><font color="#674ea7" face="monospace, monospace">import QtQuick.Controls 1.4</font></div><div><font color="#674ea7" face="monospace, monospace">import SignalTesting 1.0</font></div><div><font color="#674ea7" face="monospace, monospace"><br></font></div><div><font color="#674ea7" face="monospace, monospace">Window {</font></div><div><font color="#674ea7" face="monospace, monospace">    id: base</font></div><div><font color="#674ea7" face="monospace, monospace">    visible: true</font></div><div><font color="#674ea7" face="monospace, monospace">    width: 300</font></div><div><font color="#674ea7" face="monospace, monospace">    height: 100</font></div><div><font color="#674ea7" face="monospace, monospace">    </font></div><div><font color="#674ea7" face="monospace, monospace">    SignalTester {</font></div><div><font color="#674ea7" face="monospace, monospace">        id: st</font></div><div><font color="#674ea7" face="monospace, monospace">        onTestSignal: console.log("QML received: " + testVal)</font></div><div><font color="#674ea7" face="monospace, monospace">    }</font></div><div><font color="#674ea7" face="monospace, monospace">    Column {</font></div><div><font color="#674ea7" face="monospace, monospace">        TextInput {</font></div><div><font color="#674ea7" face="monospace, monospace">            id: txtEval</font></div><div><font color="#674ea7" face="monospace, monospace">            text: "[{foo: 'bar', baz: 1}, [1,2,3]]"</font></div><div><font color="#674ea7" face="monospace, monospace">        }</font></div><div><font color="#674ea7" face="monospace, monospace">        Button {</font></div><div><font color="#674ea7" face="monospace, monospace">            text: "sendSignal"</font></div><div><font color="#674ea7" face="monospace, monospace">            onClicked: st.sendSignal(eval(txtEval.text))</font></div><div><font color="#674ea7" face="monospace, monospace">        }</font></div><div><font color="#674ea7" face="monospace, monospace">    }</font></div><div><font color="#674ea7" face="monospace, monospace">}</font></div><div><font color="#674ea7" face="monospace, monospace">'''</font></div><div><font color="#674ea7" face="monospace, monospace"><br></font></div><div><font color="#674ea7" face="monospace, monospace">class SignalTester(QtCore.QObject):</font></div><div><font color="#674ea7" face="monospace, monospace">    testSignal = QtCore.pyqtSignal(QtCore.QVariant, arguments = ["testVal"])</font></div><div><font color="#674ea7" face="monospace, monospace">    </font></div><div><font color="#674ea7" face="monospace, monospace">    @QtCore.pyqtSlot(QtQml.QJSValue)</font></div><div><font color="#674ea7" face="monospace, monospace">    def sendSignal(self, v):</font></div><div><font color="#674ea7" face="monospace, monospace">        v = v.toVariant()</font></div><div><font color="#674ea7" face="monospace, monospace">        print("Python received: %r" % v)</font></div><div><font color="#674ea7" face="monospace, monospace">        print("Emitting signal...")</font></div><div><font color="#674ea7" face="monospace, monospace">        self.testSignal.emit(v)</font></div><div><font color="#674ea7" face="monospace, monospace"><br></font></div><div><font color="#674ea7" face="monospace, monospace"><br></font></div><div><font color="#674ea7" face="monospace, monospace">if __name__ == '__main__':</font></div><div><font color="#674ea7" face="monospace, monospace">    qmlPath = "SignalTester.qml"</font></div><div><font color="#674ea7" face="monospace, monospace">    with open(qmlPath, "w") as fp:</font></div><div><font color="#674ea7" face="monospace, monospace">        fp.write(QML)</font></div><div><font color="#674ea7" face="monospace, monospace">    app = QtWidgets.QApplication(sys.argv + ["-nograb"])</font></div><div><font color="#674ea7" face="monospace, monospace">    QtQml.qmlRegisterType(SignalTester, "SignalTesting", 1, 0, "SignalTester")</font></div><div><font color="#674ea7" face="monospace, monospace">    engine = QtQml.QQmlApplicationEngine(qmlPath)</font></div><div><font color="#674ea7" face="monospace, monospace">    sys.exit(app.exec_())</font></div></div><div><br></div><div><br></div><div><br></div>
</div>