Kivy 入門教程


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代碼中綁定了兩個Screenclass,還引用了一個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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章