Kivy+mqtt打开_消息时,出现致命Python错误:(pygame降落伞)分段错误
我将Kivy1.11.0与python 2.7.15结合使用Kivy+mqtt打开_消息时,出现致命Python错误:(pygame降落伞)分段错误,python,python-2.7,kivy,mqtt,paho,Python,Python 2.7,Kivy,Mqtt,Paho,我将Kivy1.11.0与python 2.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
#-*- 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()
我想我发现了错误的原因
有形象。
打开_消息加载图像源时,发生错误
我认为paho.mqtt callbackon_message,on_connect)值得怀疑
因为当self.changeScreen处于 def on_启动,def生成,未发生错误
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
下面的代码是错误并没有发生
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不使用图像源,则不会发生错误
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
请告诉我如何避免错误。
我想用上面的代码解决这个问题
from kivy.clock import mainthread
及
这就是问题所在-SIGSEGV分段错误
根本原因是加载映像,即应用程序正在等待映像加载
笔记
用AsyncImage替换映像将防止应用程序等待映像加载。但在加载4到5个图像/WaitScreen后,它将崩溃,IndexError:list索引超出范围
解决方案
在Python脚本中手动调用Paho MQTT循环方法。
添加了NumericProperty类型的编号,因为屏幕名称在ScreenManager中必须是唯一的。
有关详细信息,请参阅代码段、示例和输出。在这些示例中,我们使用了一个在线代理,如iot.eclipse.org上的代理
一小条
在ScreenManager中必须唯一的屏幕名称。
这是ScreenManager.current使用的名称
name是StringProperty,默认为“”
实例
main.py
输出
你有两次发布相同的代码吗?我不愿意为了确保这一点而加以区分。请澄清或编辑您的问题。uppper代码不是时钟,下面的代码是使用时钟解释更改,而不是张贴几十行相同的行。请澄清“怀疑”和“感觉不好”这两个词——这实际上与感觉无关。@3tori-port=1883或port=1883这实际上并不能解释你改变了什么,也不能解释为什么它解决了问题。请添加更多上下文,然后接受您自己的答案。
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
name
# -*- 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
from kivy.properties import NumericProperty
from kivy.clock import Clock
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: './wait.jpeg'
""")
class Charactor(Image):
pass
class InitScreen(Screen):
pass
class WaitScreen(Screen):
pass
class View(App):
def build(self):
self.number = NumericProperty(0)
self.sm = ScreenManager()
self.sm.add_widget(InitScreen(name='init'))
return self.sm
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
def on_connect(self, client, userdata, flags, response_code):
print("\non_connect:")
print("\tclient={0}, userdata={1}, flags={2}, response_code={3}".format(client, userdata, flags, response_code))
client.subscribe("$SYS/#")
def on_message(self, client, userdata, msg):
print("\non_message:")
print("\tclient={0}, userdata={1}, msg={2}".format(client, userdata, msg))
print("\tmsg.topic={0}, msg.payload={1}".format(msg.topic, msg.payload))
self.changeScreen()
self.number += 1
def changeScreen(self):
print("\nchangeScreen:")
print("\tnumber={}".format(self.number))
screen_name = 'wait{}'.format(self.number)
print("\tscreen_name={}".format(screen_name))
self.sm.add_widget(WaitScreen(name=screen_name))
self.sm.current = screen_name
def on_stop(self):
# stop the loop before exit
self.cli.loop_stop()
if __name__ == '__main__':
View().run()