QML报ReferenceError: signalEmitter未定义,但信号槽通信正常
问题
我开发了一个简单的QML+Python应用,用于测试信号槽通信功能。目前功能运行正常,但启动应用时QML侧会报错:ReferenceError: signalEmitter is not defined(位于QML文件第12行)。以下是我的代码:
QML代码:
import QtQuick 2.0 import QtQuick.Window 2.0 Window { width: 1000 height: 480 visible: true title: qsTr("Hello World") Connections { target: signalEmitter ignoreUnknownSignals : true function onSignal() { console.log("HELLO QML") } } Rectangle{ height: 100 width: 100 color: "green" MouseArea { anchors.fill: parent onClicked: { signalEmitter.sayHello() } } } Rectangle{ anchors.fill: parent color: "transparent" border.color: "black" } }
Python代码:
from PySide6.QtCore import QObject, Signal, Slot from PySide6.QtGui import QGuiApplication from PySide6.QtQml import QQmlApplicationEngine import sys class PythonSignalEmitter(QObject): signal = Signal(str) @Slot() def sayHello(self): print("HELLO PYTHON") self.signal.emit("HELLO") if __name__ == '__main__': app = QGuiApplication([]) engine = QQmlApplicationEngine() engine.load("main.qml") signal_emitter = PythonSignalEmitter() engine.rootContext().setContextProperty("signalEmitter", signal_emitter) sys.exit(app.exec())
原因分析
报错核心是代码执行顺序问题:
- 代码先调用
engine.load("main.qml")加载QML文件,此时QML开始解析渲染,Connections组件会立刻尝试访问signalEmitter上下文属性,但此时Python侧还未创建signal_emitter实例,也未将其注册到QML上下文,因此抛出引用错误。 - 后续代码才创建
signal_emitter并注册上下文属性,此时QML已完成初始渲染,但用户点击绿色矩形时,signalEmitter已存在,所以sayHello()能正常调用,信号槽通信功能也可正常运行。
解决方法
调整代码执行顺序,先注册上下文属性,再加载QML文件:
if __name__ == '__main__': app = QGuiApplication([]) engine = QQmlApplicationEngine() # 先创建实例并注册上下文属性 signal_emitter = PythonSignalEmitter() engine.rootContext().setContextProperty("signalEmitter", signal_emitter) # 再加载QML文件 engine.load("main.qml") sys.exit(app.exec())
这样QML解析时,signalEmitter已存在于上下文,不会再抛出引用错误,同时功能可正常运行。
内容的提问来源于stack exchange,提问作者codeKiller
相关产品推荐
相关产品推荐

