Kivy切换屏幕时运行循环无卡顿及终止循环实现问询
Fixing Kivy Screen Transition Scanner Input & UI Freeze Issues
Hey there! I see you're stuck with two frustrating problems when working on your Kivy app: the UI freezes up when you start the scanner input loop, and you can't terminate that loop with the Done button. Let's break this down and get things working right.
Why These Issues Are Happening
- UI Freeze: Kivy runs everything UI-related on a single main thread. When you fire up a
whileloop directly in theon_entermethod, it clogs up this thread—so the app can't process button clicks or update the screen anymore. That's why your ScreenTwo buttons are unresponsive. - Can't Terminate the Loop: Since the main thread is stuck spinning in the loop, it never gets around to checking if the Done button was pressed. Even if you tried to send 999, the loop would never notice.
The Fix: Threading + a Stop Flag
We'll move the scanner input logic to a separate thread (so it doesn't block the UI) and add a simple boolean flag to control when the loop stops. We'll also hook up the Done button to flip that flag and send the 999 signal.
Modified Python Code
from kivy.app import App from kivy.uix.screenmanager import ScreenManager, Screen from kivy.clock import Clock import threading class ScreenOne(Screen): pass class ScreenTwo(Screen): def __init__(self, **kwargs): super().__init__(**kwargs) self.scanner_running = False # Flag to control the loop self.scanner_thread = None def on_enter(self, *args): # Start the scanner loop in a background thread self.scanner_running = True self.scanner_thread = threading.Thread(target=self.listen_for_scanner) self.scanner_thread.daemon = True # Thread exits when the app closes self.scanner_thread.start() def listen_for_scanner(self): while self.scanner_running: # Replace this with your actual scanner input reading logic scanner_input = input("Scan something (or enter 999 to stop): ") if scanner_input == "999": self.scanner_running = False # Update the UI safely using Kivy's Clock (runs on main thread) Clock.schedule_once(lambda dt: self.update_scan_count(scanner_input)) def update_scan_count(self, input_val): # Update your count label here current_count = int(self.ids.scan_count.text) self.ids.scan_count.text = str(current_count + 1) def handle_done_press(self): # Stop the loop and send 999 signal self.scanner_running = False # Add code here to explicitly send 999 to your scanner if needed print("Sending 999 to terminate scanner loop") # Switch back to ScreenOne if desired self.manager.current = "screen_one" class ScannerApp(App): def build(self): sm = ScreenManager() sm.add_widget(ScreenOne(name="screen_one")) sm.add_widget(ScreenTwo(name="screen_two")) return sm if __name__ == "__main__": ScannerApp().run()
Modified KV Code
<ScreenOne>: Button: text: "Switch to Scanner Screen" size_hint: 0.6, 0.2 pos_hint: {"center_x": 0.5, "center_y": 0.5} on_press: root.manager.current = "screen_two" <ScreenTwo>: BoxLayout: orientation: "vertical" padding: 20 spacing: 20 Label: id: scan_count text: "0" font_size: 40 size_hint_y: 0.7 halign: "center" Button: text: "Done" size_hint_y: 0.3 on_press: root.handle_done_press()
Key Changes Explained
- Background Thread: The scanner input loop runs in a separate
threading.Thread, so it doesn't block the main UI thread. Thedaemon=Trueensures the thread shuts down automatically when the app closes. - Stop Flag: The
self.scanner_runningboolean acts as a switch for the loop. When the Done button is pressed, we flip it toFalseto terminate the loop. - Safe UI Updates: Kivy only allows UI changes on the main thread, so we use
Clock.schedule_onceto run theupdate_scan_countmethod in the main thread from our background thread. - Done Button Logic: The
handle_done_pressmethod stops the loop and can handle sending the 999 signal to your scanner (adjust this part to match your scanner's actual communication setup).
This should fix both the UI freeze and the loop termination problem. Feel free to tweak the scanner input logic to match your actual hardware setup!
内容的提问来源于stack exchange,提问作者Julliard
相关产品推荐
相关产品推荐

