You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

  1. UI Freeze: Kivy runs everything UI-related on a single main thread. When you fire up a while loop directly in the on_enter method, 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.
  2. 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. The daemon=True ensures the thread shuts down automatically when the app closes.
  • Stop Flag: The self.scanner_running boolean acts as a switch for the loop. When the Done button is pressed, we flip it to False to terminate the loop.
  • Safe UI Updates: Kivy only allows UI changes on the main thread, so we use Clock.schedule_once to run the update_scan_count method in the main thread from our background thread.
  • Done Button Logic: The handle_done_press method 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:42:57