在 Kivy 中无限动画化标签 - "On change screen"
Infinitely animating a label in Kivy - "On change screen"
我想为我的吉他练习制作一个快速肮脏的应用程序(为什么不呢?)并决定在没有 Kivy 经验的情况下使用 Kivy。这是一个非常简单的应用程序(代码编写得非常糟糕),有 两个屏幕和可供选择的和弦循环 。用户选择他想要练习的和弦(ToggleButtons),然后这些和弦在用户给定的时间间隔内点击“接受”按钮时在第二个屏幕上迭代动画。
但是,我在使用和弦 为第二个屏幕上的“无限变化的标签”设置动画时遇到了麻烦。我该怎么做呢?另外,如何将值(用户选择的和弦和分钟)从第一个屏幕传递到第二个屏幕的标签?
非常感谢任何帮助。希望 解决方案对于有 Kivy 经验的人来说应该非常简单。这是我的看法(工作不正常):
import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.stacklayout import StackLayout
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.animation import Animation
from kivy.clock import Clock
class MyGrid(GridLayout):
def __init__(self, **kwargs):
super(MyGrid, self).__init__(**kwargs)
self.sel_chords = []
self.time = 0
self.cols = 1
self.add_widget(Label(text="Please, select the chords you would like to practise."))
self.intro = StackLayout()
self.A = ToggleButton(text = "A", size_hint=(.2,.2))
self.intro.add_widget(self.A)
self.E = ToggleButton(text = "E", size_hint=(.2,.2))
self.intro.add_widget(self.E)
self.C = ToggleButton(text = "C", size_hint=(.2,.2))
self.intro.add_widget(self.C)
self.D = ToggleButton(text = "D", size_hint=(.2,.2))
self.intro.add_widget(self.D)
self.G = ToggleButton(text = "G", size_hint=(.2,.2))
self.intro.add_widget(self.G)
self.Cadd9 = ToggleButton(text = "Cadd9", size_hint=(.2,.2))
self.intro.add_widget(self.Cadd9)
self.add_widget(self.intro)
self.outro = GridLayout(cols=3)
self.outro.add_widget(Label(text="Seconds per chord:"))
self.minutes = TextInput(multiline=False)
self.outro.add_widget(self.minutes)
self.submit = Button(text="Accept", font_size=40)
self.submit.bind(on_press=self.pressed)
self.outro.add_widget(self.submit)
self.add_widget(self.outro)
def pressed(self, instance):
if self.A.state == "down":
self.sel_chords.append("A")
if self.C.state == "down":
self.sel_chords.append("C")
if self.D.state == "down":
self.sel_chords.append("D")
if self.E.state == "down":
self.sel_chords.append("E")
if self.G.state == "down":
self.sel_chords.append("G")
if self.Cadd9.state == "down":
self.sel_chords.append("Cadd9")
try:
self.time = int(self.minutes.text)
except:
pass
print(self.time)
self.time = 0
self.sel_chords = []
class MyGrid2(GridLayout):
def __init__(self, **kwargs):
super(MyGrid2, self).__init__(**kwargs)
self.cols = 1
self.rows = 2
self.temp = "A"
self.lbl = Label(text="A")
self.lbl.font_size = '300dp'
self.add_widget(self.lbl)
self.back = Button(text="Back", font_size=40)
self.add_widget(self.back)
#for element in itertools.cycle(["A", "B"]):
# self.lbl.text = element
def update_lbl(time):
pass #update lbl to the chords
Clock.schedule_interval(update_lbl, 1)
class MyScreenManager(ScreenManager):
def __init__(self, **kwargs):
super(MyScreenManager, self).__init__(**kwargs)
self.main_screen = Screen(name="main_screen")
self.new_screen = Screen(name="new_screen")
self.add_widget(self.main_screen)
self.add_widget(self.new_screen)
main_grid = MyGrid()
main_grid.submit.bind(on_press=self.next_screen)
self.main_screen.add_widget(main_grid)
next_grid = MyGrid2()
next_grid.back.bind(on_press=self.back_screen)
self.new_screen.add_widget(next_grid)
def next_screen(self, *args):
self.current = "new_screen"
def back_screen(self, *args):
self.current = "main_screen"
class MyApp(App):
def build(self):
return MyScreenManager()
if __name__ == "__main__":
MyApp().run()
我尽量不对您的代码进行过多更改。
所以从你离开的地方离开我使用按钮 Accept
来初始化你 next_scren
中的标签更改。有了它,我们调用函数 start
传递选定的按钮列表和时间,并使用这两个值来更新标签。
对于这次更新,我们可以安排一个时钟间隔与另一个函数来决定哪个是下一个按钮。
import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.stacklayout import StackLayout
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.animation import Animation
from kivy.clock import Clock
class MyGrid(GridLayout):
def __init__(self, **kwargs):
super(MyGrid, self).__init__(**kwargs)
self.sel_chords = []
self.time = 0
self.cols = 1
self.add_widget(Label(text="Please, select the chords you would like to practise."))
self.intro = StackLayout()
self.A = ToggleButton(text="A", size_hint=(.2, .2))
self.intro.add_widget(self.A)
self.E = ToggleButton(text="E", size_hint=(.2, .2))
self.intro.add_widget(self.E)
self.C = ToggleButton(text="C", size_hint=(.2, .2))
self.intro.add_widget(self.C)
self.D = ToggleButton(text="D", size_hint=(.2, .2))
self.intro.add_widget(self.D)
self.G = ToggleButton(text="G", size_hint=(.2, .2))
self.intro.add_widget(self.G)
self.Cadd9 = ToggleButton(text="Cadd9", size_hint=(.2, .2))
self.intro.add_widget(self.Cadd9)
self.add_widget(self.intro)
self.outro = GridLayout(cols=3)
self.outro.add_widget(Label(text="Seconds per chord:"))
self.minutes = TextInput(multiline=False)
self.outro.add_widget(self.minutes)
self.submit = Button(text="Accept", font_size=40)
self.submit.bind(on_press=self.pressed)
self.outro.add_widget(self.submit)
self.add_widget(self.outro)
def pressed(self, instance):
self.sel_chords =[]
if self.A.state == "down":
self.sel_chords.append("A")
if self.C.state == "down":
self.sel_chords.append("C")
if self.D.state == "down":
self.sel_chords.append("D")
if self.E.state == "down":
self.sel_chords.append("E")
if self.G.state == "down":
self.sel_chords.append("G")
if self.Cadd9.state == "down":
self.sel_chords.append("Cadd9")
try:
self.time = int(self.minutes.text) * 60
except:
self.time = 60
next_screen = App.get_running_app().root.get_screen("new_screen").children[0]
next_screen.start(self.sel_chords, self.time)
class MyGrid2(GridLayout):
def __init__(self, **kwargs):
super(MyGrid2, self).__init__(**kwargs)
self.cols = 1
self.rows = 2
self.temp = "A"
self.lbl = Label(text="A")
self.lbl.font_size = '300dp'
self.add_widget(self.lbl)
self.back = Button(text="Back", font_size=40)
self.add_widget(self.back)
self.selected_buttons = None
def start(self, button_list, time):
if len(button_list) == 0:
return
self.selected_buttons = button_list
self.lbl.text = self.selected_buttons[0]
Clock.schedule_interval(lambda x: self.update_lbl(self.next_button()), time)
def next_button(self):
if self.selected_buttons.index(self.lbl.text) == len(self.selected_buttons) - 1:
return 0
else:
return self.selected_buttons.index(self.lbl.text) + 1
def update_lbl(self, button, *kwargs):
self.lbl.text = self.selected_buttons[button]
class MyScreenManager(ScreenManager):
def __init__(self, **kwargs):
super(MyScreenManager, self).__init__(**kwargs)
self.main_screen = Screen(name="main_screen")
self.new_screen = Screen(name="new_screen")
self.add_widget(self.main_screen)
self.add_widget(self.new_screen)
main_grid = MyGrid()
main_grid.submit.bind(on_press=self.next_screen)
self.main_screen.add_widget(main_grid)
next_grid = MyGrid2()
next_grid.back.bind(on_press=self.back_screen)
self.new_screen.add_widget(next_grid)
def next_screen(self, *args):
self.current = "new_screen"
def back_screen(self, *args):
self.current = "main_screen"
class MyApp(App):
def build(self):
return MyScreenManager()
if __name__ == "__main__":
MyApp().run()
现在由您根据需要完善和更改此代码。
我想为我的吉他练习制作一个快速肮脏的应用程序(为什么不呢?)并决定在没有 Kivy 经验的情况下使用 Kivy。这是一个非常简单的应用程序(代码编写得非常糟糕),有 两个屏幕和可供选择的和弦循环 。用户选择他想要练习的和弦(ToggleButtons),然后这些和弦在用户给定的时间间隔内点击“接受”按钮时在第二个屏幕上迭代动画。
但是,我在使用和弦 为第二个屏幕上的“无限变化的标签”设置动画时遇到了麻烦。我该怎么做呢?另外,如何将值(用户选择的和弦和分钟)从第一个屏幕传递到第二个屏幕的标签?
非常感谢任何帮助。希望 解决方案对于有 Kivy 经验的人来说应该非常简单。这是我的看法(工作不正常):
import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.stacklayout import StackLayout
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.animation import Animation
from kivy.clock import Clock
class MyGrid(GridLayout):
def __init__(self, **kwargs):
super(MyGrid, self).__init__(**kwargs)
self.sel_chords = []
self.time = 0
self.cols = 1
self.add_widget(Label(text="Please, select the chords you would like to practise."))
self.intro = StackLayout()
self.A = ToggleButton(text = "A", size_hint=(.2,.2))
self.intro.add_widget(self.A)
self.E = ToggleButton(text = "E", size_hint=(.2,.2))
self.intro.add_widget(self.E)
self.C = ToggleButton(text = "C", size_hint=(.2,.2))
self.intro.add_widget(self.C)
self.D = ToggleButton(text = "D", size_hint=(.2,.2))
self.intro.add_widget(self.D)
self.G = ToggleButton(text = "G", size_hint=(.2,.2))
self.intro.add_widget(self.G)
self.Cadd9 = ToggleButton(text = "Cadd9", size_hint=(.2,.2))
self.intro.add_widget(self.Cadd9)
self.add_widget(self.intro)
self.outro = GridLayout(cols=3)
self.outro.add_widget(Label(text="Seconds per chord:"))
self.minutes = TextInput(multiline=False)
self.outro.add_widget(self.minutes)
self.submit = Button(text="Accept", font_size=40)
self.submit.bind(on_press=self.pressed)
self.outro.add_widget(self.submit)
self.add_widget(self.outro)
def pressed(self, instance):
if self.A.state == "down":
self.sel_chords.append("A")
if self.C.state == "down":
self.sel_chords.append("C")
if self.D.state == "down":
self.sel_chords.append("D")
if self.E.state == "down":
self.sel_chords.append("E")
if self.G.state == "down":
self.sel_chords.append("G")
if self.Cadd9.state == "down":
self.sel_chords.append("Cadd9")
try:
self.time = int(self.minutes.text)
except:
pass
print(self.time)
self.time = 0
self.sel_chords = []
class MyGrid2(GridLayout):
def __init__(self, **kwargs):
super(MyGrid2, self).__init__(**kwargs)
self.cols = 1
self.rows = 2
self.temp = "A"
self.lbl = Label(text="A")
self.lbl.font_size = '300dp'
self.add_widget(self.lbl)
self.back = Button(text="Back", font_size=40)
self.add_widget(self.back)
#for element in itertools.cycle(["A", "B"]):
# self.lbl.text = element
def update_lbl(time):
pass #update lbl to the chords
Clock.schedule_interval(update_lbl, 1)
class MyScreenManager(ScreenManager):
def __init__(self, **kwargs):
super(MyScreenManager, self).__init__(**kwargs)
self.main_screen = Screen(name="main_screen")
self.new_screen = Screen(name="new_screen")
self.add_widget(self.main_screen)
self.add_widget(self.new_screen)
main_grid = MyGrid()
main_grid.submit.bind(on_press=self.next_screen)
self.main_screen.add_widget(main_grid)
next_grid = MyGrid2()
next_grid.back.bind(on_press=self.back_screen)
self.new_screen.add_widget(next_grid)
def next_screen(self, *args):
self.current = "new_screen"
def back_screen(self, *args):
self.current = "main_screen"
class MyApp(App):
def build(self):
return MyScreenManager()
if __name__ == "__main__":
MyApp().run()
我尽量不对您的代码进行过多更改。
所以从你离开的地方离开我使用按钮 Accept
来初始化你 next_scren
中的标签更改。有了它,我们调用函数 start
传递选定的按钮列表和时间,并使用这两个值来更新标签。
对于这次更新,我们可以安排一个时钟间隔与另一个函数来决定哪个是下一个按钮。
import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.stacklayout import StackLayout
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.animation import Animation
from kivy.clock import Clock
class MyGrid(GridLayout):
def __init__(self, **kwargs):
super(MyGrid, self).__init__(**kwargs)
self.sel_chords = []
self.time = 0
self.cols = 1
self.add_widget(Label(text="Please, select the chords you would like to practise."))
self.intro = StackLayout()
self.A = ToggleButton(text="A", size_hint=(.2, .2))
self.intro.add_widget(self.A)
self.E = ToggleButton(text="E", size_hint=(.2, .2))
self.intro.add_widget(self.E)
self.C = ToggleButton(text="C", size_hint=(.2, .2))
self.intro.add_widget(self.C)
self.D = ToggleButton(text="D", size_hint=(.2, .2))
self.intro.add_widget(self.D)
self.G = ToggleButton(text="G", size_hint=(.2, .2))
self.intro.add_widget(self.G)
self.Cadd9 = ToggleButton(text="Cadd9", size_hint=(.2, .2))
self.intro.add_widget(self.Cadd9)
self.add_widget(self.intro)
self.outro = GridLayout(cols=3)
self.outro.add_widget(Label(text="Seconds per chord:"))
self.minutes = TextInput(multiline=False)
self.outro.add_widget(self.minutes)
self.submit = Button(text="Accept", font_size=40)
self.submit.bind(on_press=self.pressed)
self.outro.add_widget(self.submit)
self.add_widget(self.outro)
def pressed(self, instance):
self.sel_chords =[]
if self.A.state == "down":
self.sel_chords.append("A")
if self.C.state == "down":
self.sel_chords.append("C")
if self.D.state == "down":
self.sel_chords.append("D")
if self.E.state == "down":
self.sel_chords.append("E")
if self.G.state == "down":
self.sel_chords.append("G")
if self.Cadd9.state == "down":
self.sel_chords.append("Cadd9")
try:
self.time = int(self.minutes.text) * 60
except:
self.time = 60
next_screen = App.get_running_app().root.get_screen("new_screen").children[0]
next_screen.start(self.sel_chords, self.time)
class MyGrid2(GridLayout):
def __init__(self, **kwargs):
super(MyGrid2, self).__init__(**kwargs)
self.cols = 1
self.rows = 2
self.temp = "A"
self.lbl = Label(text="A")
self.lbl.font_size = '300dp'
self.add_widget(self.lbl)
self.back = Button(text="Back", font_size=40)
self.add_widget(self.back)
self.selected_buttons = None
def start(self, button_list, time):
if len(button_list) == 0:
return
self.selected_buttons = button_list
self.lbl.text = self.selected_buttons[0]
Clock.schedule_interval(lambda x: self.update_lbl(self.next_button()), time)
def next_button(self):
if self.selected_buttons.index(self.lbl.text) == len(self.selected_buttons) - 1:
return 0
else:
return self.selected_buttons.index(self.lbl.text) + 1
def update_lbl(self, button, *kwargs):
self.lbl.text = self.selected_buttons[button]
class MyScreenManager(ScreenManager):
def __init__(self, **kwargs):
super(MyScreenManager, self).__init__(**kwargs)
self.main_screen = Screen(name="main_screen")
self.new_screen = Screen(name="new_screen")
self.add_widget(self.main_screen)
self.add_widget(self.new_screen)
main_grid = MyGrid()
main_grid.submit.bind(on_press=self.next_screen)
self.main_screen.add_widget(main_grid)
next_grid = MyGrid2()
next_grid.back.bind(on_press=self.back_screen)
self.new_screen.add_widget(next_grid)
def next_screen(self, *args):
self.current = "new_screen"
def back_screen(self, *args):
self.current = "main_screen"
class MyApp(App):
def build(self):
return MyScreenManager()
if __name__ == "__main__":
MyApp().run()
现在由您根据需要完善和更改此代码。