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()