[英]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()
动画在调用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.