python - 发送重复命令时 Kivy GUI 冻结
问题描述
我有以下代码,我试图将时间发送到 Arduino 以显示在 OLED 上。Arduino方面运行良好,如果单独发送命令,它将显示。但是,我希望每秒更新一次时间。通过一些调整,我可以让它每 2 秒左右更新一次,有时一次显示两次。我尝试使用线程,但我不确定它是否正确。这是python脚本:
import serial
import kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.widget import Widget
from datetime import datetime, timedelta
import time
from kivy.clock import Clock
import threading
ard_connected = False
try:
ard = serial.Serial(
port='COM10',
baudrate = 9600
)
ard.flush()
ard_connected = True
except:
print("Arduino Not Connected")
Builder.load_file('Layout.kv')
class GUILayout(Widget):
def ShowTime(self, state):
threading.Timer(1, self.ShowTime).start()
now = datetime.now()
a = timedelta(seconds=1)
while state == 'down':
if (ard_connected):
current_time = now.strftime("%H:%M:%S")
ard.write(current_time.encode())
ard.flush()
now += a
if (ard_connected):
ard.write(" ".encode())
ard.flush()
class GUI(App):
def build(self):
updateClock = GUILayout()
Clock.schedule_interval(updateClock.ShowTime, 0.5)
return updateClock
if __name__ == '__main__':
GUI().run()
和 .kv 文件:
<GUILayout>
BoxLayout:
orientation: "vertical"
size: root.width, root.height
GridLayout:
cols: 2
ToggleButton:
text: "Time"
on_state: root.ShowTime(self.state)
backgrund_normal: ""
background_color: (150/255,150/255,150/255,1)
解决方案
你有太多的东西开始这个ShowTime()
方法:
Clock.schedule_interval(updateClock.ShowTime, 0.5)
和
on_state: root.ShowTime(self.state)
和
threading.Timer(1, self.ShowTime).start()
并且它们中的每一个都有可能启动一个无限循环(while state == 'down':
),因为state
传入的变量ShowTime()
永远不会改变。通过单击开始的循环ToggleButton
将在主线程中运行,冻结您的 GUI。
我相信更好的方法是ShowTime()
在一个位置启动/停止该方法。也许使用ToggleButton
.
尝试更改kv
以完成此操作:
ToggleButton:
text: "Time"
on_state: root.startShowTime(self.state) if self.state == 'down' else root.stopShowTime()
backgrund_normal: ""
background_color: (150/255,150/255,150/255,1)
并添加/更改GUILayout
和GUI
方法来支持:
class GUILayout(Widget):
def startShowTime(self, state):
self.clock_event = Clock.schedule_interval(self.ShowTime, 0.5)
def stopShowTime(self):
self.clock_event.cancel()
if (ard_connected):
ard.write(" ".encode())
ard.flush()
def ShowTime(self, dt):
if (ard_connected):
now = datetime.now()
current_time = now.strftime("%H:%M:%S")
ard.write(current_time.encode())
ard.flush()
class GUI(App):
def build(self):
updateClock = GUILayout()
return updateClock
推荐阅读
- python - Pandas 在不使用explode() 的情况下拆分行、划分和自动分配日期
- pytorch - 从同一检查点加载的两个模型(具有相似的超参数)在 PYTORCH 中给出不同的训练结果
- python - NoneType' 对象没有属性 'shape
- flutter-getx - 将其他控制器依赖项注入getx flutter中的另一个控制器是一种好习惯吗
- json - 如何使用飞镖中的冻结包序列化json?
- ssh.net - 通过 SSH.NET c# 库转发 x11
- python - 如何获取 Python Requests Library 每次重试尝试的日志?
- c - 这是什么错误,我该如何解决?错误:在 '{' 标记之前应有 '='、','、';'、'asm' 或 '__attribute__'
- android - 在 Android 中将 MySql 查询转换为 SQL Room 查询 - kotlin
- python - pygame 和 pygame.SOMETHING 之间的区别