我无法从 Python 更新 Kivy 标签的内容
I can't update the content of a Kivy label from Python
声明这是我第一次使用Kivy。
我附加的代码有效,唯一的问题是 lbl
标签不会自动更新,但只有在我按下 update
按钮时才会更新。
实际上,如果我通过“更新”按钮调用 update_lbl
函数,它会起作用,当它被 unpacking_msg
自动调用时,它什么都不做。
from email import message
from kivy.app import App
from kivy.clock import Clock
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty, StringProperty
from kivy.lang import Builder
from numpy import empty
import paho.mqtt.client as mqttClient
from queue import Queue
import threading
q=Queue()
incoming_message =''
incoming_topic =''
class Manager(ScreenManager):
pass
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
class HomeScreen(Screen):
pass
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
class MsgDecoder ():
def __init__(self,msg):
self.msg = msg
def unpacking_msg(self):
global incoming_message
global incoming_topic
incoming_topic = str(self.msg.topic)
incoming_message = str(self.msg.payload.decode("utf-8"))
MainApp().update_lbl()
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
class MqttApp():
def __init__(self,broker_address,port,user,password):
self.password = password
self.user = user
self.port = port
self.broker_address = broker_address
broker_address = "broker.hivemq.com"
port = 1883
user = ""
password = ""
try:
client = mqttClient.Client(clean_session=True, userdata=True)
client.username_pw_set(user , password)
client.connect(broker_address,port)
client.loop_start()
except:
pass
def on_connect(client, userdata, flags, rc):
client.subscribe("kivy")
def on_message(client, userdata, msg):
q.put(msg)
client.on_connect = on_connect
client.on_message = on_message
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
class MainApp(App):
lbl_txt = StringProperty()
def __init__(self):
super(MainApp, self).__init__()
self.lbl_txt = ("No message")
def switch_callback(self, switchObject, switchValue):
if(switchValue):
MqttApp.client.publish("kivy", "ON")
else:
MqttApp.client.publish("kivy", "OFF")
def update_lbl(self, *args):
self.lbl_txt=incoming_message
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
def get_msg ():
threading.Timer(1.0, get_msg).start()
while not q.empty():
msg = q.get()
if msg is None:
continue
md= MsgDecoder(msg)
md.unpacking_msg()
get_msg()
if __name__ == '__main__':
MainApp().run()
这是 Kivy 文件:
ScreenManager:
HomeScreen:
id: 'homescreen'
<HomeScreen>:
swc: swc
BoxLayout:
orientation: 'vertical'
spacing: 50
padding: 100
Label:
text: 'Remote Lamp'
Switch:
id:swc
on_active: app.switch_callback(*args)
Button:
text: "update"
on_press: app.update_lbl()
Label:
id: lbl
text: app.lbl_txt
非常感谢任何其他有用的建议!如您所见,我不是专家。
问题是你的代码:
MainApp().update_lbl()
正在创建 MainApp
的新实例并调用其 update)lbl()
方法。但是,MainApp
的新实例不是您在屏幕上看到的实例。您必须调用 运行 App
的 update_lbl()
方法。您可以使用 get_running_app()
方法来做到这一点。参见documentation。试试这个替换上面的行:
App.get_running_app().update_lbl()
声明这是我第一次使用Kivy。
我附加的代码有效,唯一的问题是 lbl
标签不会自动更新,但只有在我按下 update
按钮时才会更新。
实际上,如果我通过“更新”按钮调用 update_lbl
函数,它会起作用,当它被 unpacking_msg
自动调用时,它什么都不做。
from email import message
from kivy.app import App
from kivy.clock import Clock
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty, StringProperty
from kivy.lang import Builder
from numpy import empty
import paho.mqtt.client as mqttClient
from queue import Queue
import threading
q=Queue()
incoming_message =''
incoming_topic =''
class Manager(ScreenManager):
pass
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
class HomeScreen(Screen):
pass
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
class MsgDecoder ():
def __init__(self,msg):
self.msg = msg
def unpacking_msg(self):
global incoming_message
global incoming_topic
incoming_topic = str(self.msg.topic)
incoming_message = str(self.msg.payload.decode("utf-8"))
MainApp().update_lbl()
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
class MqttApp():
def __init__(self,broker_address,port,user,password):
self.password = password
self.user = user
self.port = port
self.broker_address = broker_address
broker_address = "broker.hivemq.com"
port = 1883
user = ""
password = ""
try:
client = mqttClient.Client(clean_session=True, userdata=True)
client.username_pw_set(user , password)
client.connect(broker_address,port)
client.loop_start()
except:
pass
def on_connect(client, userdata, flags, rc):
client.subscribe("kivy")
def on_message(client, userdata, msg):
q.put(msg)
client.on_connect = on_connect
client.on_message = on_message
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
class MainApp(App):
lbl_txt = StringProperty()
def __init__(self):
super(MainApp, self).__init__()
self.lbl_txt = ("No message")
def switch_callback(self, switchObject, switchValue):
if(switchValue):
MqttApp.client.publish("kivy", "ON")
else:
MqttApp.client.publish("kivy", "OFF")
def update_lbl(self, *args):
self.lbl_txt=incoming_message
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
def get_msg ():
threading.Timer(1.0, get_msg).start()
while not q.empty():
msg = q.get()
if msg is None:
continue
md= MsgDecoder(msg)
md.unpacking_msg()
get_msg()
if __name__ == '__main__':
MainApp().run()
这是 Kivy 文件:
ScreenManager:
HomeScreen:
id: 'homescreen'
<HomeScreen>:
swc: swc
BoxLayout:
orientation: 'vertical'
spacing: 50
padding: 100
Label:
text: 'Remote Lamp'
Switch:
id:swc
on_active: app.switch_callback(*args)
Button:
text: "update"
on_press: app.update_lbl()
Label:
id: lbl
text: app.lbl_txt
非常感谢任何其他有用的建议!如您所见,我不是专家。
问题是你的代码:
MainApp().update_lbl()
正在创建 MainApp
的新实例并调用其 update)lbl()
方法。但是,MainApp
的新实例不是您在屏幕上看到的实例。您必须调用 运行 App
的 update_lbl()
方法。您可以使用 get_running_app()
方法来做到这一点。参见documentation。试试这个替换上面的行:
App.get_running_app().update_lbl()