while for ciclos python while-loop pycharm kivy

for - ciclos en python



Usando while loop en Pycharm y Kivy (1)

¿Cómo puedo usar while loop en este código para leer serial cada 2 segundos y mostrarlo en una etiqueta? esta aplicación se colgará en ejecución y soy nuevo en Python para resolver esto.

from kivy.uix.gridlayout import GridLayout from kivy.uix.label import Label from time import sleep import serial class LoginScreen(GridLayout): def __init__(self, **kwargs): super(LoginScreen, self).__init__(**kwargs) self.cols = 2 self.rows = 2 ser = serial.Serial(''COM3'', 9600, timeout=0) while 1: sleep(2) ser.read() data = ser.read() self.add_widget(Label(text=str(data))) class MyApp(App): def build(self): return LoginScreen() if __name__ == ''__main__'': MyApp().run()


No se puede ejecutar un ciclo ''while True'' de esa manera: eso es lo que Kivy está haciendo internamente, cada iteración comprueba la entrada, actualiza la interfaz gráfica de usuario, etc. Al hacerlo usted mismo detiene el ciclo de Kivy de avanzar. Esto tampoco es solo una cuestión de kivy, sino que también funciona de la misma manera que otros frameworks de GUI, aunque no todos ejecutan las gui en el hilo principal.

El sueño también hace lo mismo: cada vez que duerme, hace exactamente eso, y el gui se congelará hasta que termine.

La solución es conectar el sistema de eventos de Kivy y usar su ciclo while interno. La forma más simple es, probablemente, agregar un nuevo método a su LoginScreen, como se muestra a continuación.

en __init__ :

self.ser = serial.Serial(''COM3'', 9600, timeout=0)

y un nuevo método:

def update(self, dt): self.ser.read() # Not sure if you''re deliberately or accidentally reading twice data = self.ser.read() self.add_widget(Label(text=str(data)))

...y entonces

from kivy.clock import Clock from functools import partial Clock.schedule_interval(self.update, 2)

El método de actualización se llamará cada 2 segundos.