2023年10月20日 星期五

Kivy screen篇 screen類 講解

簡述

screen類被用來當作screenmanager與widget的橋樑,我們通常將設計好的layout與widget放入screen類中,以便screenmanager操作。

screen類繼承自kivy.uix.relativelayout.RelativeLayout,因此也可以使用add_widget方法來添加子部件

基本範例

在main.py中寫上此段程式碼:

from kivy.app import App
from kivy.uix.screenmanager import Screen


class AScreen(Screen):
    pass


class MyApp(App):

    def build(self):
        return AScreen()


if __name__ == '__main__':
    MyApp().run()

在以上程式碼中,我創建了AScreen個screen類

在my.kv中寫上此段程式碼:

<AScreen>:

    BoxLayout:
    
        Button:
            text: 'A1'
            
        Button:
            text: 'B2'

在以上程式碼中,我在AScreen中加入了BoxLayout,並在內部加入兩個button

執行結果如下:

widget使用技巧:

attribute:

1.transition_progress:呈現轉換此screen的進度,0代表尚未呈現,1代表呈現完畢

2.transition_state:呈現此screen是退出還是進入螢幕

3.name: 藉由設定此screen的name屬性以便managerscreen可以操控其底下的screen。

4.manager: 回傳此Screen的ScreenManager

我將用以下程式碼示範以上4點(以下程式碼涉及未將解的ScreenManager與Transition,可以先跳過)

在main.py中寫上此段程式碼:

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen, SlideTransition
from kivy.properties import ObjectProperty


class AScreen(Screen):

    def btn1(self):
        print(self.transition_progress)
        print(self.transition_state)


class BScreen(Screen):

    def btn1(self):
        print(self.transition_progress)
        print(self.transition_state)


class sm(ScreenManager):
    a1 = ObjectProperty(SlideTransition(duration=30))


class MyApp(App):

    def build(self):
        return sm()


if __name__ == '__main__':
    MyApp().run()

在以上程式碼中

(1)定義AScreen類,使其繼承自Screen類,並創建btn1方法。當btn1方法被呼叫時,print(self.transition_progress)與print(self.transition_state)

(2)定義BScreen類,使其繼承自Screen類,並創建btn1方法。當btn1方法被呼叫時,print(self.transition_progress)與print(self.transition_state)

(3)定義sm類,使其繼承自ScreenManager類,並在內部定義a1為ObjectProperty類,其值為SlideTransition(duration=30)代表screen轉換模式為SlideTransition、轉換過程為30秒(這邊為了讓讀者看清楚結果才故意將動轉換過程拉長成30秒)

在my.kv中寫上此段程式碼:

<AScreen>:
    name: 'menu'

    BoxLayout:
    
        Button:
            text: 'Goto settings'
            on_press: root.manager.current = 'settings';root.btn1()
            
        Label:
            text: str(root.transition_progress)

<BScreen>:
    name: 'settings'

    BoxLayout:
    
        Label:
            text: str(root.transition_progress)
            
        Button:
            text: 'My settings button'
            
        Button:
            text: 'still settings'
            on_press: root.manager.current = 'settings';root.btn1()


<sm>:
    transition: root.a1

    AScreen:

    BScreen:

在以上程式碼中

(1)在AScreen中,加入參數name: 'menu'方便之後ScreenManager調用此Screen;加入BoxLayout,其內部有兩個Button,當按下'Goto settings' Button時,root.manager.current = 'settings'代表ScreenManager目前要展示出的Screen的name為'settings',同時呼叫btn1方法。

(2)在BScreen中,加入參數name: 'settings'方便之後ScreenManager調用此Screen;加入Label監看root.transition_progress;加入BoxLayout,其內部有兩個Button,當按下'still settings' Button時,root.manager.current = 'settings'代表ScreenManager目前要展示出的Screen的name為'settings',同時呼叫btn1方法。

(3)在sm中,加入參數transition: root.a1使sm下的Screen在轉換時套用a1的轉換模式;加入AScreen、BScreen。

執行結果如下:

以上結果的邏輯順序如下:

(1)按下'Goto settings' Button,因此root.manager.current = 'settings'使得sm將展示的Screen從'menu'變成'settings',並且輸出transition_progress為0、transition_state為out。

(2)因'menu' Screen正在離開畫面,因此transition_progress從1開始遞減;因'settings' Screen正在進入畫面,因此transition_progress從0開始遞增。

(3)畫面停止後,我們去點擊'still setting' Button,輸出transition_progress為1、transition_state為in,原因為sm依然讓'settings' Screen進入,且'settings' Screen本來就已經呈現了,因此transition_progress沒有變依然為1。

event:

1.on_pre_enter:在此Screen開始進入畫面前觸發

2.on_enter:此Screen完成進入動畫時觸發

3.on_pre_leave:在此Screen開始離開畫面前觸發

4.on_leave:此Screen完成離開動畫時觸發

我將用以下程式碼示範以上1、2點,3、4點可依此類推(以下程式碼涉及未將解的ScreenManager與Transition,可以先跳過)

在main.py中寫上此段程式碼:

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen, SlideTransition
from kivy.properties import ObjectProperty


class AScreen(Screen):

    def btn1(self):
        print(self.transition_progress)
        print(self.transition_state)

    def btn2(self):
        print('change strat')

    def btn3(self):
        print('change finish')


class BScreen(Screen):

    def btn1(self):
        print(self.transition_progress)
        print(self.transition_state)

    def btn2(self):
        print('change strat')

    def btn3(self):
        print('change finish')

class sm(ScreenManager):
    a1 = ObjectProperty(SlideTransition(duration=30))


class MyApp(App):

    def build(self):
        return sm()


if __name__ == '__main__':
    MyApp().run()


與上一個例子相比,這邊我多加了btn2、btn3方法,除此之別無差別

<AScreen>:
    name: 'menu'
    on_pre_enter: root.btn2()
    on_leave: root.btn3()

    BoxLayout:
        Button:
            text: 'Goto settings'
            on_press: root.manager.current = 'settings';root.btn1()
        Label:
            text: str(root.transition_progress)


<BScreen>:
    name: 'settings'
    on_pre_enter: root.btn2()
    on_leave: root.btn3()

    BoxLayout:
        Label:
            text: str(root.transition_progress)
        Button:
            text: 'My settings button'
        Button:
            text: 'still settings'
            on_press: root.manager.current = 'menu';root.btn1()


<sm>:
    transition: root.a1

    AScreen:

    BScreen:

與上一個例子相比,這邊我多加了on_pre_enter與on_leave方法,除此之別無差別。

執行結果如下:



沒有留言:

張貼留言

精選文章

Kivy UIX篇 widget篇 TabbedPanel類 event篇 講解