I state that this is the first time I use Kivy.
The code I attached works, the only problem is that the lbl
label does not update automatically but only if I press the update
button.
In practice, if I call the update_lbl
function via the “update” button it works, when it is called automatically by unpacking_msg
it does nothing.
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()
Here is the Kivy file:
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
I really appreciate any other helpful advice! I am not an expert as you can see.
Advertisement
Answer
The problem is that your code:
MainApp().update_lbl()
is creating a new instance of MainApp
and calling its update)lbl()
method. However, that new instance of MainApp
is not the instance that you see on the screen. You must call the update_lbl()
method of the running App
. You can do that by using the get_running_app()
method. See the documentation. Try this replacement for the above line:
App.get_running_app().update_lbl()