PySide6中QQuickWidget设上下文属性后QML无法接收Qt信号问题排查
QML无法捕获PySide6 Qt端信号的问题排查与解决
问题根源
- ContextProperty设置时机错误:你在调用
qw.setSource('view.qml')之后才设置rootContext().setContextProperty('message', self.message),此时QML已经完成加载,上下文属性无法被QML识别。 - QML中多余的属性定义:你在QML的Rectangle里定义了
property QtObject message,这会覆盖上下文传入的同名全局对象,导致Connections的target是未初始化的空对象。
修复后的代码
修改后的main.py
调整设置ContextProperty和加载QML的顺序:
import sys from PySide6.QtCore import QObject, Signal from PySide6.QtWidgets import ( QApplication, QMainWindow, QGridLayout, QHBoxLayout, QVBoxLayout, QSizePolicy, QLabel, QPushButton, QLineEdit, QSpacerItem, QWidget ) from PySide6.QtQuickWidgets import QQuickWidget class Message(QObject): updated = Signal(str, arguments=['msg']) def __init__(self): super().__init__() def set_message(self, msg): print(f'emitting signal with message: {msg}') self.updated.emit(msg) class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle('QQuickWidget Example') # create QQuickWidget self.qw = QQuickWidget() self.qw.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) self.qw.setResizeMode(QQuickWidget.SizeRootObjectToView) # 先设置上下文属性,再加载QML self.message = Message() self.qw.engine().rootContext().setContextProperty('message', self.message) # 现在加载QML self.qw.setSource('view.qml') self.lineedit = QLineEdit() self.button = QPushButton('Start') self.button.clicked.connect(self.on_button_clicked) grid = QGridLayout() grid.addWidget(QLabel('Enter: '), 0, 0, 1, 1) grid.addWidget(self.lineedit, 0, 1, 1, 1) grid.addWidget(self.button, 1, 0, 1, 2) vertical_layout = QVBoxLayout() vertical_layout.addLayout(grid) vertical_layout.addSpacerItem(QSpacerItem(1, 1, QSizePolicy.Minimum)) main_layout = QHBoxLayout() main_layout.addLayout(vertical_layout) main_layout.addWidget(self.qw) main_layout.setStretch(0, 1) widget = QWidget() widget.setLayout(main_layout) self.setCentralWidget(widget) def on_button_clicked(self): msg = self.lineedit.text() self.message.set_message(msg) if __name__ == '__main__': app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec())
修改后的view.qml
移除多余的property QtObject message定义:
import QtQuick Rectangle { property string newText: "Hello" id: root width: 500 height: 500 color: "white" Text { id: text anchors.fill: parent text: newText font.pixelSize: 24 color: "blue" } Connections { target: message function onUpdated(msg) { newText = msg console.log(msg) } } }
说明
- 调整顺序后,QML加载时能正确获取到上下文传入的
message对象。 - 移除QML中的重复属性定义,确保
Connections的target指向Qt端创建的Message实例,这样信号就能被正确捕获。
内容的提问来源于stack exchange,提问作者DailyLearner
相关产品推荐
相关产品推荐

