【发布时间】:2015-01-20 18:43:45
【问题描述】:
来自 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
最好的,
马库斯
【问题讨论】: