You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 09:01:04