Из QML я хотел бы:
- Вызов слота Python.
- Передайте обратный вызов.
- Запустите этот обратный вызов после заполнения слота.
Я пробовал это:
- Зарегистрируйте свойство контекста (
Service
) - Звоните
Service.request("data", function (response) { console.log(response) }
- В Python функция принимается как
QtQml.QJSValue
- Функция вызывается в отдельном потоке после какой-то дорогостоящей операции
Однако эта функция оказывает эффект только иногда, а в большинстве случаев вообще не действует или приводит к сбою интерпретатора Python. Если я уберу вызов time.sleep(1)
, это, скорее всего, даст результаты.
Есть идеи?
Вот нерабочая реализация вышеизложенного
main.qml
import QtQuick 2.3
import "application.js" as App
Rectangle {
id: appWindow
width: 200
height: 200
Component.onCompleted: App.onLoad()
}
main.py
import sys
import time
import threading
from PyQt5 import QtCore, QtGui, QtQml, QtQuick
class Service(QtCore.QObject):
def __init__(self, parent=None):
super(Service, self).__init__(parent)
@QtCore.pyqtSlot(str, str, QtCore.QVariant, QtQml.QJSValue)
def request(self, verb, endpoint, data, cb):
"""Expensive call"""
print verb, endpoint, data
self.cb = cb
def thread():
time.sleep(1)
event = QtCore.QEvent(1000)
event.return_value = "expensive result"
QtGui.QGuiApplication.postEvent(self, event)
worker = threading.Thread(target=thread)
worker.daemon = False
worker.start()
self.worker = worker
def event(self, event):
if event.type() == 1000:
self.cb.call([event.return_value])
return super(Service, self).event(event)
app = QtGui.QGuiApplication(sys.argv)
view = QtQuick.QQuickView()
context = view.rootContext()
service = Service()
context.setContextProperty("Service", service)
view.setSource(QtCore.QUrl("main.qml"))
view.show()
app.exec_()
application.js
"use strict";
/*global print, Service*/
function onLoad() {
Service.request("POST", "/endpoint", {"data": "value"}, function (reply) {
print(reply);
print(reply);
print(reply);
});
print("request() was made");
}
Реализация адаптирована отсюда
https://github.com/ben-github/PyQt5-QML-CallbackFunction
С наилучшими пожеланиями,
Маркус