Kivy+mqttWhen on_消息,致命的Python错误:(pygame降落伞)分段Fau

2024-04-18 03:18:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用的是kivy1.11.0和python2.7.15。在

#-*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.image import Image
from kivy.lang import Builder
Builder.load_string("""
<InitScreen>:
    AnchorLayout:
        anchor_x:"center"
        anchor_y:"center"
        Label:
            text:"init"
<WaitScreen>:
    Image:
        id:charactor
        pos_hint:{'center_x':.5,'y':0 }
        size_hint:1,1
        source:'./wait1.png'
""")

class Charactor(Image):
    pass
class InitScreen(Screen):
    pass
class WaitScreen(Screen):
    def __init__(self, **kwargs):
        super(WaitScreen, self).__init__(**kwargs)


class View(App):
    sm = ScreenManager()
    cli = mqtt.Client(protocol=mqtt.MQTTv311)
    def __init__(self, **kwargs):
        super(View, self).__init__(**kwargs)

    def build(self):
        self.sm.add_widget(InitScreen(name='init'))
        self.sm.current='init'
        return self.sm

    def on_start(self):
        self.cli.on_connect = self.on_connect
        self.cli.on_message = self.on_message
        self.cli.connect('localhost', port=1883, keepalive=60)
        self.cli.loop_start()

    def on_connect(self,client, userdata, flags, respons_code):
        print('status {0}'.format(respons_code))
        client.subscribe('get/test')

    def on_message(self,client, userdata, msg):
        self.changeScreen()

    def changeScreen(self,**kwargs):
        self.sm.add_widget(WaitScreen(name='wait'))
        self.sm.current='wait'

if __name__ == '__main__':
    View().run()

如果get消息(on U消息),则更改屏幕

但是错误发生了

^{pr2}$

我想查出了错误的原因 有形象。 打开“加载图像源”消息时,发生错误 我想泛美卫生组织回调(on_message,on_connect)可疑

因为什么时候自我更改屏幕()在def-on-start,def-build中,未发生错误

下面的代码是错误没有发生

class View(App):
    sm = ScreenManager()
    cli = mqtt.Client(protocol=mqtt.MQTTv311)
    waitflag = False
    def __init__(self, **kwargs):
        super(View, self).__init__(**kwargs)

    def build(self):
        self.sm.add_widget(InitScreen(name='init'))
        self.sm.current='init'
        return self.sm

    def on_start(self):
        self.cli.on_connect = self.on_connect
        self.cli.on_message = self.on_message
        self.cli.connect('localhost', port=1883, keepalive=60)
        self.cli.loop_start()
        Clock.schedule_interval(self.changeScreen, 1) 

    def on_connect(self,client, userdata, flags, respons_code):
        print('status {0}'.format(respons_code))
        client.subscribe('get/test')

    def on_message(self,client, userdata, msg):
        self.waitflag = True

    def changeScreen(self,dt):
        if self.waitflag:
            self.sm.add_widget(WaitScreen(name='wait'))
            self.sm.current='wait'
            self.waitflag = False

但是这个代码感觉不好,因为如果WaitScreen不使用图像源,则不会发生错误

请告诉我如何避免错误。 我想用上层代码


Tags: importselfclientmessagecliinitondef
2条回答

这个问题解决了。在

from kivy.clock import mainthread

以及

^{pr2}$

仅此而已

问题-SIGSEGV(分段错误)

根本原因是加载映像,也就是说,应用程序正在等待加载映像。在

注意

Image替换为AsyncImage将防止应用程序在加载映像之前等待。但是在加载4到5个images/WaitScreen之后,它将崩溃IndexError: list index out of range。在

解决方案

  1. 在Python脚本中手动调用Paho MQTT loop()方法。在
  2. 添加了number类型的number,因为屏幕名称在屏幕管理器中必须是唯一的。在

有关详细信息,请参阅代码片段、示例和输出。在示例中,我们使用一个在线代理,比如iot.eclipse.org。在

代码段

def on_start(self):
    self.number = 0
    self.cli = mqtt.Client(protocol=mqtt.MQTTv311)
    self.cli.on_connect = self.on_connect
    self.cli.on_message = self.on_message
    self.cli.connect("iot.eclipse.org", port=1883, keepalive=60)
    Clock.schedule_interval(self.loop, 0.5)    # call loop every 0.5 seconds

def loop(self, dt):
    # manually call the Paho MQTT loop() method
    self.cli.loop(0.1)  # blocks for 100 ms

Screen » name

name

Name of the screen which must be unique within a ScreenManager. This is the name used for ScreenManager.current.

name is a StringProperty and defaults to ‘’.

示例

在主.py在

^{pr2}$

输出

Img01

相关问题 更多 >