Kivy總體思想是:kv代碼管界面,python代碼管邏輯。
然後重點來了, 我主要講三件事:(kv訪問Python;Python訪問kv;窗口)。
一階段:
1.Python訪問kv
Python可以直接調用kv代碼。如:
from kivy.app import App
from kivy.lang import Builder
kv = Builder.load_string('''
Button:
text: "I was created by kv codes"
''')
class TestApp(App):
def build(self):
return kv
TestApp().run()
2.窗口
kv代碼中被<>
包裹住的是某個class的名字,這個class需在python代碼中聲明,它們代表同一個class。
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen
Builder.load_string('''
<OneScreen>
Label:
text: "My mother screen was created by kv and python codes."
''')
class OneScreen(Screen):
pass
class TestApp(App):
def build(self):
return OneScreen()
TestApp().run()
3. kv訪問Python
在.kv文件或kv代碼裏,root只代表其上層被<>包裹住的類。如:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen
Builder.load_string('''
<OneScreen>
Button:
text: 'Click me'
on_release: print(root.__class__)
''')
class OneScreen(Screen):
pass
class TestApp(App):
def build(self):
return OneScreen()
TestApp().run()
二階段:
1. kv訪問Python
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen
Builder.load_string('''
<OneScreen>
BoxLayout:
Button:
text: 'Click me'
on_release: root.do_something()
Button:
text: 'Who made this?'
on_release: print(root.author)
''')
class OneScreen(Screen):
def __init__(self, **kwargs):
self.author = 'yingshaoxo'
super(OneScreen, self).__init__(**kwargs)
def do_something(self):
print('2333')
class TestApp(App):
def build(self):
return OneScreen()
TestApp().run()
2. Python訪問kv
你需要給kv組件一個id,用以標明其唯一性。再使用ids方法調用它。如:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen
Builder.load_string('''
<OneScreen>
BoxLayout:
Button:
id: one_ask
text: 'Who made this?'
on_release: root.do_something()
''')
class OneScreen(Screen):
def __init__(self, **kwargs):
self.author = 'yingshaoxo'
super(OneScreen, self).__init__(**kwargs)
def do_something(self):
self.ids['one_ask'].text = self.author
class TestApp(App):
def build(self):
return OneScreen()
TestApp().run()
3. 窗口
As far as I see,在做程序的時候,你會遇到很多窗口。所以ScreenManager
這時候派上用場了。
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager
Builder.load_string('''
<ScreenManager>:
Screen:
name: 'home'
Button:
text: 'Go to another screen'
on_release: root.current = 'another'
Screen:
name: 'another'
Button:
text: "Go back home"
on_release: root.current = 'home'
''')
class ScreenManager(ScreenManager):
pass
class TestApp(App):
def build(self):
return ScreenManager()
TestApp().run()
三階段:
1+2. 窗口、kv訪問Python
In fact, 你可以把ScreenManager
看成一個很大的widget
。
但如果所有的數據操作(root.function
)都在一個 ScreenManager
class裏做的話顯然不科學。
所以我們最好把每個窗口都在Python裏聲明一個class,這樣既可以有程序啓動時的總操作,又可以有各個子窗口的分操作。看示例:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
Builder.load_string('''
<ScreenManager>:
HomeScreen
AnotherScreen
<HomeScreen>:
name: 'home'
Button:
text: 'Go to another screen'
on_release: root.manager.current = 'another'
<AnotherScreen>:
name: 'another'
Button:
text: "Go back home"
on_release: root.manager.current = 'home'
''')
class ScreenManager(ScreenManager):
pass
class HomeScreen(Screen):
pass
class AnotherScreen(Screen):
pass
class TestApp(App):
def build(self):
return ScreenManager()
TestApp().run()
我們可以看到示例不光在kv代碼中綁定了兩個Screen
class,還引用了一個root.manager
。沒錯,那是從screen
class得到screenmanager
class的方法。
3. Python訪問kv
直接用kv代碼預先定義控件(如按鈕)的行爲有時不能滿足我們的需求,於是我們可能需要臨時改變按鈕的行爲:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen
from time import gmtime, strftime # this equls cv codes #...
Builder.load_string("""
#:import gmtime time.gmtime
#:import strftime time.strftime
<RootWidget>
BoxLayout:
orientation: 'vertical'
Button:
id: change_itself
text: 'I can change myself'
on_release: root.ids['change_itself'].text = strftime("%a, %d %b %Y %H:%M:%S", gmtime())
Button:
id: change_all
text: 'I can change our behavior'
on_release: root.change_all()
""")
class RootWidget(Screen):
def change_all(self):
print(self.ids)
for instance_class in self.ids.values():
instance_class.text = 'Exit'
instance_class.bind(on_release=exit)
class TestApp(App):
def build(self):
return RootWidget()
if __name__ == '__main__':
TestApp().run()
四階段:
1. kv訪問Python
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen
Builder.load_string('''
<OneScreen>
Label:
text: app.saying
''')
class OneScreen(Screen):
pass
class TestApp(App):
def __init__(self, **kwargs):
self.saying = 'I was read from app instance.'
super(OneScreen, self).__init__(**kwargs)
def build(self):
return OneScreen()
TestApp().run()
五階段:Show time!
還想什麼呢?趕緊動手寫程序吧~
For more information, you can go and see:
https://kivy.org/docs/api-kivy.uix.screenmanager.html
https://github.com/yingshaoxo/kivy-chat