如何在kivy中只让函数休眠而不是让整个程序休眠
how to make only the function sleep instead of the entire program in kivy
基本上,睡眠会停止整个脚本,这不好,我很可能不希望这样,所以有什么解决方案吗? (这是给这里这个男孩的):
def on_button_click(self):
global started
if started==False:
started=True
enemyname = self.ids.starta.text
self.type_text("")
self.hide_widget(self.ids.starta)
self.hide_widget(self.ids.startb)
self.ids.thingy.opacity = 1
self.ids.thingys.opacity = 1
self.ids.thingyss.opacity = 1
self.type_text("type this text")
sleep(3)
print("yes")
正如你在这里看到的,我已经测试了一些东西,睡眠上方的功能被延迟了 3 秒,但打印立即打印出来,不知道如何完全解释它,但这肯定会导致问题,因为你可以看到,无论如何我可以解决这个问题? (self.type_text 使用 Clock.schedule_interval 并且该函数来自我最近问过的另一个问题)
所以是的,主要问题是:我如何做到只有这个按钮功能暂停而不是整个功能
所有相关部分:
Builder.load_string("""
<BoxLayout>:
orientation:"vertical"
spacing:"10dp"
TextInput:
text: "type enemy name"
size_hint:1,3
id: starta
Button:
text:"Start"
on_press: root.on_button_click()
size_hint:1,3
id: startb
Label:
id: label
text: "Enter enemy name and press 'start'"
Button:
text:"Fight"
size_hint: 1,.3
color:1,0,0,1
background_color:.5,0,0
opacity:0
id: thingy
Button:
text:"Guard"
size_hint: 1,.3
color:0,0,1,1
background_color:0,0,.5
opacity:0
id: thingys
Button:
text:"Heal"
size_hint: 1,.3
color:0,1,0,1
background_color:0,.5,0
opacity:0
id: thingyss
""")
class TextBox(BoxLayout):
cache_text = StringProperty("") # For storing the entered text.
index = NumericProperty(0) # For iteration over cache_text.
global started
def hide_widget(self, wid, dohide=True):
if hasattr(wid, 'saved_attrs'):
if not dohide:
wid.height, wid.size_hint_y, wid.opacity, wid.disabled = wid.saved_attrs
del wid.saved_attrs
elif dohide:
wid.saved_attrs = wid.height, wid.size_hint_y, wid.opacity, wid.disabled
wid.height, wid.size_hint_y, wid.opacity, wid.disabled = 0, None, 0, True
def type_text(self, txt, time=0.07):
self.ids.label.text = "" # Comment it out to retain the text.
self.cache_text = txt # Store the entered text here.
# For more control you may use method Clock.create_trigger.
self.ev = Clock.schedule_interval(self.update_text, time) # Update text after every 0.25 sec.
def update_text(self, *args):
if self.index < len(self.cache_text):
val = self.cache_text[self.index]
self.ids.label.text += val # Appending to existing text.
self.index += 1
else:
self.index = 0 # Reset index.
self.cache_text = "" # Clear cache.
self.ev.cancel() # Cancel text updation.
def on_button_click(self):
global started
if started==False:
started=True
enemyname = self.ids.starta.text
self.type_text("")
self.hide_widget(self.ids.starta)
self.hide_widget(self.ids.startb)
self.ids.thingy.opacity = 1
self.ids.thingys.opacity = 1
self.ids.thingyss.opacity = 1
self.type_text("who you are fighting againist is %s, be careful. they are strong."% enemyname)
class Test(App):
def build(self):
return TextBox()
Test().run()
看来你在做某种 GUI。
GUI 的标准是创建第二个线程来进行实际处理。
这是因为如果您在同一个线程中处理 GUI 运行,它实际上保持冻结状态,因为它无法处理来自用户的事件。
处理线程还必须向 GUI 线程发送事件,以通知处理完成。
所以你想要这样的东西:
from time import sleep
from threading import Thread
class ProcessingThread(Thread):
def run(self):
sleep(20)
print('ciao')
p=ProcessingThread()
p.start()
请注意,您实现了一个 run
函数,但您调用了 start
。
如果你直接调用run
,它就像一个正常的函数一样运行,但是start
是Thread
class中的方法,它实际上创建了线程并且然后在内部调用 run
函数。
基本上,睡眠会停止整个脚本,这不好,我很可能不希望这样,所以有什么解决方案吗? (这是给这里这个男孩的):
def on_button_click(self):
global started
if started==False:
started=True
enemyname = self.ids.starta.text
self.type_text("")
self.hide_widget(self.ids.starta)
self.hide_widget(self.ids.startb)
self.ids.thingy.opacity = 1
self.ids.thingys.opacity = 1
self.ids.thingyss.opacity = 1
self.type_text("type this text")
sleep(3)
print("yes")
正如你在这里看到的,我已经测试了一些东西,睡眠上方的功能被延迟了 3 秒,但打印立即打印出来,不知道如何完全解释它,但这肯定会导致问题,因为你可以看到,无论如何我可以解决这个问题? (self.type_text 使用 Clock.schedule_interval 并且该函数来自我最近问过的另一个问题)
所以是的,主要问题是:我如何做到只有这个按钮功能暂停而不是整个功能
所有相关部分:
Builder.load_string("""
<BoxLayout>:
orientation:"vertical"
spacing:"10dp"
TextInput:
text: "type enemy name"
size_hint:1,3
id: starta
Button:
text:"Start"
on_press: root.on_button_click()
size_hint:1,3
id: startb
Label:
id: label
text: "Enter enemy name and press 'start'"
Button:
text:"Fight"
size_hint: 1,.3
color:1,0,0,1
background_color:.5,0,0
opacity:0
id: thingy
Button:
text:"Guard"
size_hint: 1,.3
color:0,0,1,1
background_color:0,0,.5
opacity:0
id: thingys
Button:
text:"Heal"
size_hint: 1,.3
color:0,1,0,1
background_color:0,.5,0
opacity:0
id: thingyss
""")
class TextBox(BoxLayout):
cache_text = StringProperty("") # For storing the entered text.
index = NumericProperty(0) # For iteration over cache_text.
global started
def hide_widget(self, wid, dohide=True):
if hasattr(wid, 'saved_attrs'):
if not dohide:
wid.height, wid.size_hint_y, wid.opacity, wid.disabled = wid.saved_attrs
del wid.saved_attrs
elif dohide:
wid.saved_attrs = wid.height, wid.size_hint_y, wid.opacity, wid.disabled
wid.height, wid.size_hint_y, wid.opacity, wid.disabled = 0, None, 0, True
def type_text(self, txt, time=0.07):
self.ids.label.text = "" # Comment it out to retain the text.
self.cache_text = txt # Store the entered text here.
# For more control you may use method Clock.create_trigger.
self.ev = Clock.schedule_interval(self.update_text, time) # Update text after every 0.25 sec.
def update_text(self, *args):
if self.index < len(self.cache_text):
val = self.cache_text[self.index]
self.ids.label.text += val # Appending to existing text.
self.index += 1
else:
self.index = 0 # Reset index.
self.cache_text = "" # Clear cache.
self.ev.cancel() # Cancel text updation.
def on_button_click(self):
global started
if started==False:
started=True
enemyname = self.ids.starta.text
self.type_text("")
self.hide_widget(self.ids.starta)
self.hide_widget(self.ids.startb)
self.ids.thingy.opacity = 1
self.ids.thingys.opacity = 1
self.ids.thingyss.opacity = 1
self.type_text("who you are fighting againist is %s, be careful. they are strong."% enemyname)
class Test(App):
def build(self):
return TextBox()
Test().run()
看来你在做某种 GUI。
GUI 的标准是创建第二个线程来进行实际处理。
这是因为如果您在同一个线程中处理 GUI 运行,它实际上保持冻结状态,因为它无法处理来自用户的事件。
处理线程还必须向 GUI 线程发送事件,以通知处理完成。
所以你想要这样的东西:
from time import sleep
from threading import Thread
class ProcessingThread(Thread):
def run(self):
sleep(20)
print('ciao')
p=ProcessingThread()
p.start()
请注意,您实现了一个 run
函数,但您调用了 start
。
如果你直接调用run
,它就像一个正常的函数一样运行,但是start
是Thread
class中的方法,它实际上创建了线程并且然后在内部调用 run
函数。