当前位置: 首页 > news >正文

Pyside6 + QML - 信号与槽04 - Python 主动发射信号驱动 QML UI

导言


在前面的示例中,交互主要由 QML 调用 Python 函数完成,Python 端处于被动响应。本篇将演示如何由 Python 主动发射信号并驱动 QML UI 更新,实现从“被动调用”到“主动推送”的双向交互。
在这里插入图片描述
这张图描述了 Python 端通过信号(Signal)把字符串传递给 QML。QML 接收到信号后,更新界面上的标签文字,从而实现 Python 主动驱动 QML UI。

效果如下所示:
在这里插入图片描述
工程代码:

  • github: https://github.com/q164129345/myPyside6_QML/tree/main/basic05_signal
  • gitee: https://gitee.com/wallace89/myPyside6_QML/tree/main/basic05_signal

一、main.py


# python3.10.11 - PySide6==6.9
import sys
from PySide6.QtCore import QObject, Slot, Signal, QTimer
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngineclass Backend(QObject):# 定义信号messageChanged = Signal(str)def __init__(self):super().__init__() # 初始化父类self.counter = 0# 创建QTimer定时器,每秒触发一次(不要使用python自带的定时器,会卡UI)self.timer = QTimer(self)self.timer.timeout.connect(self.updateMessage)self.timer.start(1000)  # 1000毫秒def updateMessage(self):# 每1秒发送一次信号self.counter += 1self.messageChanged.emit(f"Hello from Python! {self.counter}") # 发送信号if __name__ == "__main__":# 创建应用程序和引擎app = QGuiApplication(sys.argv)engine = QQmlApplicationEngine()# qml与python交互backend = Backend() # 实例化python后端对象engine.rootContext().setContextProperty("backend", backend) # 注册到QML环境(名叫 “backend”)# 加载QML文件engine.addImportPath(sys.path[0])  # 当前项目路径engine.loadFromModule("Example", "Main")  # 模块(Example) + QML文件名(Main.qml)if not engine.rootObjects():sys.exit(-1)sys.exit(app.exec())

关键点说明

class Backend(QObject):# 定义信号messageChanged = Signal(str)def __init__(self):super().__init__() # 初始化父类self.counter = 0# 创建QTimer定时器,每秒触发一次self.timer = QTimer(self)self.timer.timeout.connect(self.updateMessage)self.timer.start(1000)  # 1000毫秒def updateMessage(self):# 每1秒发送一次信号self.counter += 1self.messageChanged.emit(f"Hello from Python! {self.counter}") # 发送信号
  • messageChanged = Signal(str):创建一个信号,名为messageChanged,传递消息的类型是字符串。
  • super().__init__():因为显式重写了__init__()构造函数,记得调用super().__init__()初始化父类QObject。另外,如果没有重写__init__()的话,Python会自动帮我们调用super().__init__()。所以,之前的例子都不需要调用super().__init__()
  • self.messageChanged.emit():是将字符串“信号“发送给QML。emit() 方法用于触发/发送之前定义的 messageChanged 信号,这是Qt信号-槽机制中的"发送端"。

二、Main.qml


// 导入QML基础模块,包含基本的QML元素
import QtQuick 2.15
// 导入Qt控件模块,包含Button等界面控件
import QtQuick.Controls 2.15// 应用程序主窗口
ApplicationWindow {visible: true          // 窗口可见width: 400            // 窗口宽度为400像素height: 300           // 窗口高度为300像素title: qsTr("Python主动更新 -> QML显示")  // 窗口标题,qsTr用于国际化Label {id: labelanchors.centerIn: parent  // 标签居中显示text: "等待Python消息..."    // 标签初始文本内容}// 绑定Python信号Connections {target: backend  // 连接到名为backend的Python对象function onMessageChanged(msg) {label.text = msg  // 更新标签文本为传递的新文本}}
}

关键点说明

// 绑定Python信号
Connections {target: backend  // 连接到名为backend的Python对象function onMessageChanged(msg) {label.text = msg  // 更新标签文本为传递的新文本}
}
  • Connections :是QML中的一个特殊元素,用于建立信号-槽连接,它允许QML对象监听其他对象的信号。
  • target:指定要监听的对象(比如Backend对象)。
  • function onMessageChanged(msg)onMessageChanged是信号处理器的命名约定(不能随意更改),当Python端的 messageChanged信号发出时,这个函数会自动被调用。

为什么不能用其他名字?
这是Qt/QML框架的约定规则,具体原因:

  1. 自动连接机制:QML引擎会自动识别以on开头且后面跟着信号名的函数,并将其作为该信号的处理器
  2. 命名转换规则:
    • Python信号:messageChanged
    • QML处理函数:onMessageChanged
    • 规则:on + 信号名(首字母大写)
  3. 框架内部实现:Qt的元对象系统依赖这种命名约定来建立信号和槽之间的连接
    这就像是一个"合约",Python端发出messageChanged信号,QML端必须用onMessageChanged来接收,这样Qt框架才知道它们是对应的。
http://www.dtcms.com/a/390132.html

相关文章:

  • 【系列文章】Linux系统中断的应用06-中断线程化
  • ruoyi-vue(十五)——布局设置,导航栏,侧边栏,顶部栏
  • 第13章 线程池配置
  • 任天堂获得新专利:和《宝可梦传说:阿尔宙斯》相关
  • Redis MONITOR 命令详解
  • 七、Java-多线程、网络编程
  • 三轴云台之动态补偿机制篇
  • MySQL备份与恢复实战指南:从原理到落地,守护数据安全
  • 手机上记录todolist待办清单的工具选择用哪一个?
  • 仓颉编程语言青少年基础教程:Interface(接口)
  • 用 go-commons 打造一个轻量级内置监控系统,让服务开箱即用
  • PyQt6之QSpinBox计数器应用
  • 大模型应用开发4-MCP实战
  • Ruoyi-vue-plus-5.x第八篇文件管理与存储: 8.3 文件处理功能
  • 【51单片机】【protues仿真】基于51单片机PM2.5温湿度测量蓝牙系统
  • 病毒学原理
  • 怎样快速搭建一个高效的数据存储系统:Python实战指南
  • 音频驱动视频生成新突破:Wan2.2-S2V 模型全面体验与教程
  • 关于pc端分页+h5端加载更多的vue3简单钩子函数
  • MySQL 练习题
  • 推客小程序二级分销机制设计与实现:从0到1搭建裂变增长引擎
  • 【C++】多态(上)
  • uos中创建自定义Ip (192.168.137.1)的热点的方法
  • 【每日算法】搜索插入位置 LeetCode
  • vue+springboot+ngnix前后端分离项目部署
  • sward入门到实战(1) - 安装教程
  • 独立站的优势有哪些
  • Java学习历程18——哈希表的使用
  • 机械传动里的名词——传动比
  • qiankun 主子应用部署教程(Nginx 小白版)