为什么我的 kivy 加载屏幕动画不移动? Stuck/frozen 节目?
Why doesn't my kivy load screen animation move? Stuck/frozen program?
我已经使用 Kivy 开发应用程序一段时间了,现在正在做最后的润色。几天来我一直在寻找解决我的问题的方法,但无济于事。我已经按各种顺序尝试了 Threading、Clock 和 运行 函数,以尝试使其正常工作。我在下面复制了一个工作示例,但尽可能简化了它,以免使我的 post 变大。在我真实应用程序的 get_briefing
和 strip_first_brief
函数中,我有几个 POST 请求和几个 GET 请求,执行时间从 5 到 20 秒不等。因此,我在每一个中都实现了 time.sleep(5)
来模拟工作时间。这给出了与我的真实应用程序完全相同的结果。停止动画的不仅仅是 POST 或 GET 函数,而是涉及的每个进程....
由于这些加载时间,我还切入一个角落进入我的加载屏幕,其中我的按钮 on_press
立即更改屏幕,否则随着卡片转换,屏幕卡在大约 1/5 到过渡。在这个程序中我显然有不止一个问题需要解决,我认为如果我能解决“冻结的应用程序”问题,大多数问题都会得到解决...
如果有人可以复制并测试我提供的程序,并提供解决方案,我将不胜感激。我在这个问题上被困了太久了(字面意思)。
main.py
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, NoTransition, CardTransition, SwapTransition
from kivy.uix.button import ButtonBehavior
from kivy.uix.image import Image
from kivy.animation import Animation
import time
from threading import Thread
class ImageButton(ButtonBehavior, Image):
pass
class HomeScreen(Screen):
pass
class Results1Screen(Screen):
pass
class LoadScreen(Screen):
pass
GUI = Builder.load_file("main.kv")
class TestApp(App):
def build(self):
return GUI
def change_screen(self, screen_name):
screen_manager = self.root.ids['screen_manager']
screen_manager.current = screen_name
def widget_thread(self):
p1 = Thread(target=self.spin_widget())
p1.start()
#Clock.schedule_once(lambda dt: self.spin_widget(), 0)
def spin_widget(self):
widget = self.root.ids["load_screen"].ids["spinning_widget"]
anim = Animation(angle=-3000, duration=40)
anim.start(widget)
def immediate_screen1(self):
self.root.ids["screen_manager"].transition = NoTransition()
self.change_screen("load_screen")
self.root.ids["screen_manager"].transition = CardTransition()
def thread1(self, dest1, dest2):
self.thread = 1
p2 = Thread(target=self.get_briefing(dest1, dest2))
p2.start()
def get_briefing(self, dest1, dest2):
time.sleep(5)
def strip_first_brief(self, destX, etaX):
time.sleep(5)
#p3 = Thread(self.strip_first_brief(dest2, eta2))
#p3.start()
TestApp().run()
main.kv
#:import utils kivy.utils
#:include kv/homescreen.kv
#:include kv/results1screen.kv
#:include kv/loadscreen.kv
GridLayout:
cols: 1
FloatLayout:
canvas:
Color:
rgb: utils.get_color_from_hex("#000523")
Rectangle:
size: self.size
pos: self.pos
rows: 1
pos_hint: {"top": 1, "left": 1}
size_hint: 1, .04
ScreenManager:
size_hint: 1, .8
pos_hint: {"top": .8, "left": 1}
id: screen_manager
HomeScreen:
name: "home_screen"
id: home_screen
Results1Screen:
name: "results_1_screen"
id: results_1_screen
LoadScreen:
name: "load_screen"
id: load_screen
homescreen.kv
<HomeScreen>:
FloatLayout:
canvas:
Color:
rgb: utils.get_color_from_hex("#000523")
Rectangle:
size: self.size
pos: self.pos
TextInput:
id: manual_dest1
hint_text: "first destination"
text: self.text.upper() if self.text is not None else ''
size_hint: .7, .08
pos_hint: {"top": .75, "center_x": .5}
TextInput:
id: eta1
hint_text: "first ETA in UTC"
text: self.text.upper() if self.text is not None else ''
size_hint: .7, .08
pos_hint: {"top": .5, "center_x": .5}
Button:
text: "Strip TAF"
pos_hint: {"top": .15, "center_x": .5}
size_hint: .5, .08
padding: 20, 20
opacity: 1 if self.state == 'normal' else .5
on_press:
app.immediate_screen1()
app.widget_thread()
on_release:
app.thread1(manual_dest1.text, manual_dest2.text)
app.strip_first_brief(manual_dest1.text, eta1.text)
app.change_screen("results_1_screen")
results1screen.kv
<Results1Screen>:
FloatLayout:
canvas:
Color:
rgb: utils.get_color_from_hex("#000523")
Rectangle:
size: self.size
pos: self.pos
Label:
rows: 1
text: "RESULTS\nblah\nblah\nblah"
pos_hint: {"top": .95, "center_x": .5}
size_hint: 1, .05
loadscreen.kv
<LoadScreen>:
FloatLayout:
canvas:
Color:
rgb: utils.get_color_from_hex("#000523")
Rectangle:
size: self.size
pos: self.pos
Label:
text: "loading"
SpinningWidget:
id: spinning_widget
source: "icons/turbine.png"
angle: 0
size_hint: .15, .15
pos_hint: {"center_x": .5, "center_y": .6}
<SpinningWidget@Image>
angle: 0
canvas.before:
PushMatrix
Rotate:
angle: root.angle
axis: 0, 0, 1
origin: root.center
canvas.after:
PopMatrix
当你尝试这个时,显然不需要输入目的地或预计到达时间。也没有提供图像,但你会看到正方形在卡住之前旋转了大约 2 度,然后在最后一秒再次看到它试图再次旋转。对于冗长的post,我深表歉意,但我没有其他方法可以解决这个问题。请帮助....
p2 = Thread(target=self.get_briefing(dest1, dest2))
这个 调用 self.get_briefing
并将结果传递给目标,即它等同于:
result = self.get_briefing(dest1, dest2)
p2 = Thread(target=result)
你可能想传入要调用的函数作为参数,比如
p2 = Thread(target=lambda: self.get_briefing(dest1, dest2))
我已经使用 Kivy 开发应用程序一段时间了,现在正在做最后的润色。几天来我一直在寻找解决我的问题的方法,但无济于事。我已经按各种顺序尝试了 Threading、Clock 和 运行 函数,以尝试使其正常工作。我在下面复制了一个工作示例,但尽可能简化了它,以免使我的 post 变大。在我真实应用程序的 get_briefing
和 strip_first_brief
函数中,我有几个 POST 请求和几个 GET 请求,执行时间从 5 到 20 秒不等。因此,我在每一个中都实现了 time.sleep(5)
来模拟工作时间。这给出了与我的真实应用程序完全相同的结果。停止动画的不仅仅是 POST 或 GET 函数,而是涉及的每个进程....
由于这些加载时间,我还切入一个角落进入我的加载屏幕,其中我的按钮 on_press
立即更改屏幕,否则随着卡片转换,屏幕卡在大约 1/5 到过渡。在这个程序中我显然有不止一个问题需要解决,我认为如果我能解决“冻结的应用程序”问题,大多数问题都会得到解决...
如果有人可以复制并测试我提供的程序,并提供解决方案,我将不胜感激。我在这个问题上被困了太久了(字面意思)。
main.py
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, NoTransition, CardTransition, SwapTransition
from kivy.uix.button import ButtonBehavior
from kivy.uix.image import Image
from kivy.animation import Animation
import time
from threading import Thread
class ImageButton(ButtonBehavior, Image):
pass
class HomeScreen(Screen):
pass
class Results1Screen(Screen):
pass
class LoadScreen(Screen):
pass
GUI = Builder.load_file("main.kv")
class TestApp(App):
def build(self):
return GUI
def change_screen(self, screen_name):
screen_manager = self.root.ids['screen_manager']
screen_manager.current = screen_name
def widget_thread(self):
p1 = Thread(target=self.spin_widget())
p1.start()
#Clock.schedule_once(lambda dt: self.spin_widget(), 0)
def spin_widget(self):
widget = self.root.ids["load_screen"].ids["spinning_widget"]
anim = Animation(angle=-3000, duration=40)
anim.start(widget)
def immediate_screen1(self):
self.root.ids["screen_manager"].transition = NoTransition()
self.change_screen("load_screen")
self.root.ids["screen_manager"].transition = CardTransition()
def thread1(self, dest1, dest2):
self.thread = 1
p2 = Thread(target=self.get_briefing(dest1, dest2))
p2.start()
def get_briefing(self, dest1, dest2):
time.sleep(5)
def strip_first_brief(self, destX, etaX):
time.sleep(5)
#p3 = Thread(self.strip_first_brief(dest2, eta2))
#p3.start()
TestApp().run()
main.kv
#:import utils kivy.utils
#:include kv/homescreen.kv
#:include kv/results1screen.kv
#:include kv/loadscreen.kv
GridLayout:
cols: 1
FloatLayout:
canvas:
Color:
rgb: utils.get_color_from_hex("#000523")
Rectangle:
size: self.size
pos: self.pos
rows: 1
pos_hint: {"top": 1, "left": 1}
size_hint: 1, .04
ScreenManager:
size_hint: 1, .8
pos_hint: {"top": .8, "left": 1}
id: screen_manager
HomeScreen:
name: "home_screen"
id: home_screen
Results1Screen:
name: "results_1_screen"
id: results_1_screen
LoadScreen:
name: "load_screen"
id: load_screen
homescreen.kv
<HomeScreen>:
FloatLayout:
canvas:
Color:
rgb: utils.get_color_from_hex("#000523")
Rectangle:
size: self.size
pos: self.pos
TextInput:
id: manual_dest1
hint_text: "first destination"
text: self.text.upper() if self.text is not None else ''
size_hint: .7, .08
pos_hint: {"top": .75, "center_x": .5}
TextInput:
id: eta1
hint_text: "first ETA in UTC"
text: self.text.upper() if self.text is not None else ''
size_hint: .7, .08
pos_hint: {"top": .5, "center_x": .5}
Button:
text: "Strip TAF"
pos_hint: {"top": .15, "center_x": .5}
size_hint: .5, .08
padding: 20, 20
opacity: 1 if self.state == 'normal' else .5
on_press:
app.immediate_screen1()
app.widget_thread()
on_release:
app.thread1(manual_dest1.text, manual_dest2.text)
app.strip_first_brief(manual_dest1.text, eta1.text)
app.change_screen("results_1_screen")
results1screen.kv
<Results1Screen>:
FloatLayout:
canvas:
Color:
rgb: utils.get_color_from_hex("#000523")
Rectangle:
size: self.size
pos: self.pos
Label:
rows: 1
text: "RESULTS\nblah\nblah\nblah"
pos_hint: {"top": .95, "center_x": .5}
size_hint: 1, .05
loadscreen.kv
<LoadScreen>:
FloatLayout:
canvas:
Color:
rgb: utils.get_color_from_hex("#000523")
Rectangle:
size: self.size
pos: self.pos
Label:
text: "loading"
SpinningWidget:
id: spinning_widget
source: "icons/turbine.png"
angle: 0
size_hint: .15, .15
pos_hint: {"center_x": .5, "center_y": .6}
<SpinningWidget@Image>
angle: 0
canvas.before:
PushMatrix
Rotate:
angle: root.angle
axis: 0, 0, 1
origin: root.center
canvas.after:
PopMatrix
当你尝试这个时,显然不需要输入目的地或预计到达时间。也没有提供图像,但你会看到正方形在卡住之前旋转了大约 2 度,然后在最后一秒再次看到它试图再次旋转。对于冗长的post,我深表歉意,但我没有其他方法可以解决这个问题。请帮助....
p2 = Thread(target=self.get_briefing(dest1, dest2))
这个 调用 self.get_briefing
并将结果传递给目标,即它等同于:
result = self.get_briefing(dest1, dest2)
p2 = Thread(target=result)
你可能想传入要调用的函数作为参数,比如
p2 = Thread(target=lambda: self.get_briefing(dest1, dest2))