Я вижу несколько проблем в вашем примере.
- Будьте осторожны с именами переменных. Например,
x
почти всегда является NumericProperty
виджета. - Когда вы ссылаетесь на атрибут в python, используйте
self
, или виджеты x
в вашем случае не изменятся. - Если у вас есть цикл в kivy, вы заблокируете приложение. Таким образом, вы либо используете
Clock
или threading
. Я буду предлагать threading
вместо Clock
при использовании последовательного порта, потому что readline()
также заблокирует приложение при ожидании ввода. - Вы на самом деле никогда не звоните
tm()
Итак, вот что я хотел бы изменить в MainWindow
классе, и еще несколько импортов.
import serial
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.uix.button import Button
from kivy.properties import StringProperty
from kivy.clock import mainthread
import threading
KV = """
WindowManager:
MainWindow:
<MainWindow>:
Label:
size: 75, 50
size_hint: None, None
pos_hint: {'right': 1, 'bottom': 1}
background_color: (1.0, 0.0, 0.0, 1.0)
text: root.label_text
"""
class MainWindow(Screen):
label_text = StringProperty("")
def __init__(self, **kwargs):
super(MainWindow, self).__init__(**kwargs)
threading.Thread(target=self.tm).start()
def tm(self):
while (1):
with serial.Serial('COM4', 9600) as ser:
value = ser.readline()
ser.close()
self.update_label(value.decode("ascii").strip())
@mainthread
def update_label(self, value):
self.label_text = value
class WindowManager(ScreenManager):
pass
class MyMainApp(App):
def build(self):
return Builder.load_string(KV)
if __name__ == "__main__":
MyMainApp().run()
Обязательно используйте mainthread
при изменении любого элемента пользовательского интерфейса в другом потоке. В этом случае при изменении свойства строки будет меняться отображение.