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

如何将Paho-MQTT的on_message变量传递到Kivy应用中?

解决Paho-MQTT回调变量传递到Kivy应用的问题

问题分析

你的代码存在两个核心问题:

  1. 提前执行UI操作:在on_start中直接调用add_widget时,gmsg还未被MQTT回调赋值,此时添加的组件内容为空或报错。
  2. 线程安全问题:Paho-MQTT的on_message回调运行在子线程中,直接操作Kivy UI组件会触发跨线程错误,之前使用@mainthread可能是装饰位置不正确导致未生效。

解决方案

修改代码,确保UI操作在主线程执行,并在收到MQTT消息时动态添加组件:

  1. 导入Kivy的主线程装饰器:
from kivy.clock import mainthread
  1. 修改on_start方法中的回调逻辑,移除全局变量,通过self访问应用实例,并在UI操作前添加@mainthread装饰:
class MyApp(MDApp):
    def build(self):
        self.theme_cls.theme_style = "Light"
        self.theme_cls.primary_palette = "BlueGray"
        self.title = "IAD"
        return Builder.load_file("my.kv")
    
    def remove_item(self, instance):
        self.root.get_screen('Home').ids.md_list.remove_widget(instance)

    def on_start(self):
        topic = "python/mqtt"
        
        def onConnect(client, userdata, flags, rc):
            mqttc.subscribe(topic, 0)
        
        @mainthread  # 确保UI操作在主线程执行
        def update_ui(message):
            # 收到消息后动态添加组件
            self.root.get_screen('Home').ids.md_list.add_widget(
                SwipeToDeleteItem(text=message)
            )
        
        def onMessage(client, userdata, msg):
            msg_content = msg.payload.decode('utf-8')
            print(msg_content)
            # 调用主线程的UI更新函数
            update_ui(msg_content)
        
        mqttc = mqtt.Client(client_id="kivy", clean_session=True)
        mqttc.on_connect = onConnect
        mqttc.on_message = onMessage
        mqttc.connect('broker.emqx.io', 1883, keepalive=60, bind_address="")
        mqttc.loop_start()

MyApp().run()

关键说明

  • 主线程装饰:将UI更新逻辑封装在update_ui函数中,并用@mainthread装饰,确保这部分代码在Kivy的主线程中执行,避免跨线程错误。
  • 动态添加组件:只有在收到MQTT消息时才调用add_widget,保证组件内容是最新的消息内容。
  • 避免全局变量:通过self直接访问应用的UI元素,比全局变量更安全且易于维护。

内容的提问来源于stack exchange,提问作者Sh2071

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 17:30:21