Как я могу отправить словарь Python в интерфейс QML с сигналом? - PullRequest
0 голосов
/ 19 февраля 2019

Я хочу отправить словари, содержащие данные, которые мне нужны для динамического создания объектов 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...

Можете ли вы сказать мне, что я делаю не так?Есть ошибки в коде или это невозможно сделать?

1 Ответ

0 голосов
/ 19 февраля 2019

Подпись, которую вы должны использовать в сигнале: 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)
...