Я заявляю, что это первый раз, когда я использую 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()
Вот файл Киви:
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
— это не тот экземпляр, который вы видите на экране. Вы должны вызвать метод update_lbl()
запущенного App
. Вы можете сделать это, используя метод get_running_app()
. См. документация. Попробуйте эту замену для приведенной выше строки:
App.get_running_app().update_lbl()
Дайте мне знать, что еще вы бы изменили.
Большое спасибо, я догадался, в чем проблема, но я не знал, как ее решить. В настоящее время работает.