Unsolved Unable to store javascript callback in C++?
-
I am trying to pass a javascript callback to a C++ slot and then call that callback again after some time has passed, for example after an http request returns. It appears as though the
QJSValue
becomes corrupt after the call to the C++ slot stack frame is cleaned up. How is it possible to store a callback in c++ and then call it later?The following pyqt5 example demonstrates how the callback is passed correctly to the slot as a callable
QJSValue
but becomes not callable if referenced after the slot returns, i.e. through a timer.from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtQml import * from PyQt5.QtQuick import * from PyQt5.QtQuickWidgets import * class Widget(QWidget): def __init__(self): super().__init__() self._callback = None self.qml = QQuickWidget(self) self.qml.rootContext().setContextProperty('widget', self) self.qml.setSource(QUrl.fromLocalFile('test_qml.qml')) self.startTimer(10) @pyqtSlot(QJSValue) def doCallback(self, callback): print('doCallback: callable?', callback.isCallable(), 'isNull?', callback.isNull()) self._callback = callback def timerEvent(self, e): if self._callback is not None: print('timerEvent: callable?', self._callback.isCallable(), 'isNull?', self._callback.isNull()) if self._callback.isCallable(): self._callback.call([1, 2]) self._callback = None import sys app = QApplication(sys.argv) w = Widget() w.show() app.exec()
test_qml.qml
import QtQuick 2.14 Item { function callback() { print('callback()') } Component.onCompleted: widget.doCallback(callback) }
prints the following output:
patrick$ python test_qml.py doCallback: callable? True isNull? False timerEvent: callable? False isNull? False patrick$