簡體   English   中英

Kivy GUI 在發送重復命令時凍結

[英]Kivy GUI freezes when sending repeated commands

我有以下代碼,我試圖將時間發送到 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': ),因為傳遞給ShowTime()state變量永遠不會改變。 通過單擊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)

並添加/更改GUILayoutGUI方法以支持:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM