繁体   English   中英

无法禁用 Kivy (Python) 中的按钮

[英]Cannot disable buttons in Kivy (Python)

我在禁用 kivy 库中的按钮时遇到问题。 当我禁用按钮时,它根本不会禁用。 它以某种奇怪的方式等待。

让我向您展示我的代码:

import kivy 
from kivy.app import App 
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
import time

class MainApp(App): 
    def build(self):            
        self.l = FloatLayout()      
        b = Button(text="BUTTON", pos_hint={"top":0.8, "right": 0.8}, size_hint=(0.6, 0.6))
        b.bind(on_press=self.press)     
        self.l.add_widget(b)
        return self.l
    
    def press(self, btn):
        btn.disabled = True
        time.sleep(3.0)
        btn.disabled = False    
        
app = MainApp()
app.run()

当我按下按钮时,我想禁用它 3 秒。 但是它不是程序“冻结”(不禁用按钮),然后在 3 秒后执行按下动画(按钮闪烁蓝色)。 由于 time.sleep(3.0),当然程序必须“冻结”,但是在禁用按钮后(必须是灰色的,但它不会改变颜色......)

如何解决? 如果我把 time.sleep() 放在那里,比如 for cycle(大约有 1000 万个循环)来模仿程序“做某事”,它的行为方式相同......

那么我该如何解决呢? 如何禁用kivy中的按钮,然后做一些事情,完成后再次启用按钮?

谢谢!

编辑:我的问题不是,该程序冻结了 3 秒钟。 我知道调用 time.sleep() 是阻塞的。 我不明白的是为什么按钮在睡觉之前(和期间)没有被禁用......

time.sleep阻塞了代码。 相反,您需要使用Clock在 3 秒后启用该按钮。 以下是实现目标的更正代码:

import kivy 
from kivy.app import App 
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.clock import Clock
from functools import partial

class MainApp(App): 
    def build(self):            
        self.l = FloatLayout()      
        b = Button(text="BUTTON", pos_hint={"top":0.8, "right": 0.8}, size_hint=(0.6, 0.6))
        b.bind(on_press=self.press)     
        self.l.add_widget(b)
        return self.l
    
    def press(self, btn):
        btn.disabled = True
        Clock.schedule_once(partial(self.btn_enable, btn), 3)
        
    def btn_enable(self, btn, *args):
        btn.disabled = False
        
app = MainApp()
app.run()

TL; DR

动画调用press函数发生。 这意味着在执行time.sleep冻结程序。

该怎么办?

相反,您需要做一些非阻塞的事情,这意味着它会在三秒钟内运行,但不会导致程序冻结。 可能可行的方法是利用线程(类似于示例,但处理跨线程发送变量)。

例子

这是您的代码不起作用的示例,因此您可以了解其要点。 最有可能的是,您将不得不处理跨线程传递变量的问题:

import kivy 
from kivy.app import App 
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
# import time
import threading 

class MainApp(App): 
    def build(self):            
        self.l = FloatLayout()      
        b = Button(text="BUTTON", pos_hint={"top":0.8, "right": 0.8}, size_hint=(0.6, 0.6))
        b.bind(on_press=self.press)     
        self.l.add_widget(b)
        return self.l
    
    def press(self, btn):
        btn.disabled = True
        # time.sleep(3.0)
        threading.Timer(3.0, lambda: btn.disabled = False).start()
        
app = MainApp()
app.run()

这是受到这个答案的启发。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM