Я получаю вывод из шкалы в порядке, используя Pyserial. Поэтому я решил прочитать все выходные данные в Kivy Label, чтобы сделать программу более удобной для пользователя. Сначала минимальный пример был достаточно хорош, в результате чего пользователь просто нажимал кнопку, чтобы увидеть результат в 20 интервалов счетчика. Но теперь необходимо автоматизировать весь процесс, сначала получив выходные данные, а затем вызвав вторичное событие, которое проверяет стабильный вывод перед обновлением базы данных Sqlite. Но возникла одна проблема:
1] Метка не обновляется при изменении выходных данных весов. Это связано с методом serial.readline()
, который по какой-то причине также не обновляется.
Часть моего кода на Python:
import kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import StringProperty, ObjectProperty,BooleanProperty,NumericProperty
from kivy.clock import Clock
from kivy.core.window import Window
import serial, re, time, string, random
import plyer
Builder.load_string("""
#:set cereal None
<CerealOutput>:
Label:
text: root.portname
pos_hint: {'top': 0.79, 'right': 0.8}
size_hint: [0.6, 0.19]
color: (1,1,1,1)
Label:
id: milk
text: root.scale_output if root.scale_output != "" else "Scale Output"
pos_hint: {'top': 0.6, 'right': 0.8}
size_hint: [0.6, 0.2]
color: (1,1,1,1)
canvas.before:
Color:
rgb: (0.43, 0.43, 0.43, 1)
Rectangle:
pos: self.pos
size: self.size
Button:
text: "Exit"
pos_hint: {'top': 0.2, 'right': 0.98}
size_hint: [0.17, 0.18]
on_release: root.weigh_tick.cancel() if root.weigh_tick != None else ""
Button:
text: "Get Serial"
pos_hint: {'top': 0.3, 'right': 0.8}
size_hint: [0.6, 0.2]
on_press:
cereal = root.ccereal
root.GetCereal() if cereal == None or cereal.isOpen() == False else root.weight_ticker()
""")
class CerealOutput(FloatLayout):
portname = StringProperty('')
the = ObjectProperty(None) # App object
ccereal = ObjectProperty(None)
mythread = ObjectProperty(None)
bowl = ObjectProperty(None)
go = BooleanProperty(True)
weigh_tick = ObjectProperty(None)
weigh_tme = NumericProperty() # Weigh time numerical
scale_output = StringProperty('')
is_shift = BooleanProperty(False)
def __init__(self, **kwargs):
super(CerealOutput, self).__init__(**kwargs)
self.the = App.get_running_app()
self.bowl = self.ids.milk
def GetCereal(self):
ser = serial.Serial(port='/dev/ttyUSB0',baudrate=9600,bytesize=serial.EIGHTBITS)
self.ccereal = ser
if self.ccereal.isOpen():
self.portname = self.ccereal.name
else:
self.ccereal.open()
self.portname = self.ccereal.name
self.weight_ticker()
def GetOutput(self, cereal):
if cereal.isOpen() and cereal != None:
if self.weigh_tme > 0:
try:
bb = cereal.readline()
t = ''.join(random.choice(string.ascii_letters) for x in range(5))
self.scale_output = re.sub('[GSTUkg,\s]', '', bb.decode('latin-1'))
#Q only gets text after each read is finished. Why?
#S Threading; Interval read; Other
#UI imbed visible progress on each read
#Errors, Test if port exists, Unicode byte read error: How to solve
print(self.scale_output, bb, t)
self.weigh_tick()
self.weigh_tme -= 1
except serial.SerialException:
self.weigh_tme = 0
print("Port not open")
else:
self.weigh_tick.cancel() # cancel event
print("Finished")
else:
self.GetCereal()
def weight_ticker(self):
self.weigh_tme = 1000
self.weigh_tick = Clock.create_trigger(lambda dt: self.GetOutput(self.ccereal), 1)
self.weigh_tick()
class PorridgeApp(App):
def build(self):
return CerealOutput()
def on_stop(self):
if App.get_running_app().root.ccereal != None:
App.get_running_app().root.ccereal.close()
def on_pause(self):
if App.get_running_app().root.ccereal != None:
App.get_running_app().root.ccereal.close()
pass
if __name__=='__main__':
PorridgeApp().run()
Я попытался связать вывод с текстом объекта Label. Это не имело значения.
Может, кто-нибудь подскажет, почему метод readline
не обновляется при изменении выходных данных весов?