Kivy でアプリを作成-ページ遷移【Python】

Kivy
スポンサーリンク
スポンサーリンク

はじめに

前回までは、各 Widget の使い方について説明しました。

今回は、ページ遷移の方法について説明します。

前提条件

前提条件は以下の通りです。

  • Python がインストールされている
  • Windows11 (Ubuntuでも可?)
  • Kivy[full] がインストールされている

ページ遷移プログラム

詳細な説明はこちらの公式ページにあります。

まずは、kv ファイルを作成します。

<MainWidget>:
    BoxLayout: 
        orientation: 'vertical'
        padding: [20, 20]
        Label:
            text: "Main Menu"
            size_hint: 1.0, 0.3
            font_size: 30
        Button:
            text: 'A'
            on_release: root.manager.current = 'a_widget'
            size_hint: 1.0, 0.15
            font_size: 25
        Button:
            text: "B"
            on_release: root.manager.current = 'b_widget'
            size_hint: 1.0, 0.15
            font_size: 25
        Button:
            text: "C"
            size_hint: 1.0, 0.15
            on_release: root.manager.current = 'c_widget'
            font_size: 25
        Label:
            text: ""
            size_hint: 1.0, 0.25

<AWidget>:
    BoxLayout:
        Label:
            text: "this is A Widget Page"
            font_size: 45
        Button:
            text: "back to main"
            font_size: 45
            on_release: root.manager.current = 'main'

<BWidget>:
    BoxLayout:
        Label:
            text: "this is B Widget Page"
            font_size: 45
        Button:
            text: "go to A"
            font_size: 45
            on_release: root.move_page()

<CWidget>:
    BoxLayout:
        Label:
            text: "this is C Widget Page"
            font_size: 45
        Button:
            text: "go to b"
            font_size: 45
            on_release: root.manager.current = 'b_widget'

画面は全部で 4 つあります。
root.manager.current = PageName で、ページ遷移が可能になります。

続いて、Python プログラムです。

from kivy.app import App
from kivy.lang.builder import Builder
Builder.load_file('test_3.kv')

from kivy.core.window import Window
Window.size = (960, 540)

from kivy.uix.screenmanager import ScreenManager, Screen

class MainWidget(Screen):
    pass

class AWidget(Screen):
    pass

class BWidget(Screen):
    def move_page(self):
        self.manager.current = "a_widget"

class CWidget(Screen):
    pass


class MyApp(App):
    def build(self):
        self.sm = ScreenManager()
        self.sm.add_widget(MainWidget(name='main'))
        self.sm.add_widget(AWidget(name='a_widget'))
        self.sm.add_widget(BWidget(name='b_widget'))
        self.sm.add_widget(CWidget(name='c_widget'))
        return self.sm


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

ScreenManager のインスタンスを作成し、そこにクラスを追加していきます。

以上で準備は完了です。さっそく実行してみます。

C のボタンをクリックします。

go to b をクリックします。

go to A をクリックします。

back to main をクリックすると、メインページに戻ります。

ページ遷移のオプション

アニメーション方向の変更

ページ遷移には、遷移のアニメーション方向を指定することができます。

kv ファイルのみ変更します。

<MainWidget>:
    BoxLayout: 
        orientation: 'vertical'
        padding: [20, 20]
        Label:
            text: "Main Menu"
            size_hint: 1.0, 0.3
            font_size: 30
        Button:
            text: 'A'
            on_release: 
                root.manager.current = 'a_widget'
                root.manager.transition.direction = 'left'
            size_hint: 1.0, 0.15
            font_size: 25
        Button:
            text: "B"
            on_release: 
                root.manager.current = 'b_widget'
                root.manager.transition.direction = 'left'
            size_hint: 1.0, 0.15
            font_size: 25
        Button:
            text: "C"
            size_hint: 1.0, 0.15
            on_release: 
                root.manager.current = 'c_widget'
                root.manager.transition.direction = 'left'
            font_size: 25
        Label:
            text: ""
            size_hint: 1.0, 0.25

<AWidget>:
    BoxLayout:
        Label:
            text: "this is A Widget Page"
            font_size: 45
        Button:
            text: "back to main"
            font_size: 45
            on_release: 
                root.manager.current = 'main'
                root.manager.transition.direction = 'right'

<BWidget>:
    BoxLayout:
        Label:
            text: "this is B Widget Page"
            font_size: 45
        Button:
            text: "go to A"
            font_size: 45
            on_release: 
                root.move_page()
                root.manager.transition.direction = 'down'

<CWidget>:
    BoxLayout:
        Label:
            text: "this is C Widget Page"
            font_size: 45
        Button:
            text: "go to b"
            font_size: 45
            on_release: 
                root.manager.current = 'b_widget'
                root.manager.transition.direction = 'down'

ページ遷移の方向として、メインから遷移は左へ遷移、サブからサブ(C→B→A)は上へ遷移といったように、感覚的に進む・戻るを再現すると分かりやすいアプリになります。

on_release: 
    root.manager.current = 'b_widget'
    root.manager.transition.direction = 'down'

新しく登場しましたが、on_release でインテントを使用すると、複数の関数を実行することができます。カンマ (,) で区切っても可能ですが、インテントの方が分かりやすいです。

root.manager.transition.direction = ‘down’ で遷移方向を変更できます。
up, down, left, right の4 種類から選択できます。

アニメーション自体の変更

以下のアニメーションが選択可能です。

  • NoTransition … 遷移アニメーションなし、瞬間的に遷移
  • SlideTransition … スライドアニメーション、デフォルトの遷移方法
  • CardTransition … オーバーライドしながら遷移、スライド方向指定可能
  • SwapTransition … 立体的な回転テーブルのように遷移
  • FadeTransition … パワーポイントのフェードのように遷移
  • WipeTransition … パワーポイントのワイプのように遷移
  • FallOutTransition … 画面の奥に落ちていくような遷移
  • RiseInTransition … FallOutTransition の逆

以下のように指定することが可能です。他の部分は割愛します。

from kivy.uix.screenmanager import (NoTransition, SlideTransition, 
    CardTransition, SwapTransition, FadeTransition, 
    WipeTransition, FallOutTransition, RiseInTransition)

class MyApp(App):
    def build(self):
        self.sm = ScreenManager(transition=RiseInTransition())
        self.sm.add_widget(MainWidget(name='main'))
        self.sm.add_widget(AWidget(name='a_widget'))
        self.sm.add_widget(BWidget(name='b_widget'))
        self.sm.add_widget(CWidget(name='c_widget'))
        return self.sm

別のクラスの関数を使用

あるページで別のページに割り当てられた関数を実行したいときがあります。
以下が、その例となります。

kv ファイル

<MainWidget>:
    BoxLayout: 
        orientation: 'vertical'
        padding: [20, 20]
        Label:
            text: "Main Menu"
            size_hint: 1.0, 0.3
            font_size: 30
        Button:
            text: 'A'
            on_release: 
                root.manager.current = 'a_widget'
                root.manager.transition.direction = 'left'
            size_hint: 1.0, 0.15
            font_size: 25
        Button:
            text: "B"
            on_release: 
                root.manager.current = 'b_widget'
                root.manager.transition.direction = 'left'
            size_hint: 1.0, 0.15
            font_size: 25
        Button:
            text: "C"
            size_hint: 1.0, 0.15
            on_release: 
                root.manager.current = 'c_widget'
                root.manager.transition.direction = 'left'
            font_size: 25
        Label:
            text: ""
            size_hint: 1.0, 0.25

<AWidget>:
    BoxLayout:
        Label:
            text: "this is A Widget Page"
            font_size: 45
        Button:
            text: "back to main"
            font_size: 45
            on_release: 
                root.manager.current = 'main'
                root.manager.transition.direction = 'right'

<BWidget>:
    BoxLayout:
        Label:
            text: "this is B Widget Page"
            font_size: 45
        Button:
            text: "go to A"
            font_size: 45
            on_release: 
                root.move_page()
                root.manager.transition.direction = 'down'

<CWidget>:
    AWidget:
        id: A_Widget
    BoxLayout:
        Label:
            text: "this is C Widget Page"
            font_size: 45
        Button:
            text: "go to b"
            font_size: 45
            on_release: 
                A_Widget.print_test()
                root.manager.current = 'b_widget'
                root.manager.transition.direction = 'down'

py ファイル

from kivy.app import App
from kivy.lang.builder import Builder
Builder.load_file('test_3.kv')

from kivy.core.window import Window
Window.size = (960, 540)

from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.screenmanager import (NoTransition, SlideTransition, 
    CardTransition, SwapTransition, FadeTransition, 
    WipeTransition, FallOutTransition, RiseInTransition)

from kivy.uix.widget import Widget

class MainWidget(Screen):
    pass

class AWidget(Screen):
    def print_test(self):
        print("this is A widget")

class BWidget(Screen):
    def move_page(self):
        self.manager.current = "a_widget"

class CWidget(Screen):
    pass


class MyApp(App):
    def build(self):
        self.sm = ScreenManager(transition=RiseInTransition())
        self.sm.add_widget(MainWidget(name='main'))
        self.sm.add_widget(AWidget(name='a_widget'))
        self.sm.add_widget(BWidget(name='b_widget'))
        self.sm.add_widget(CWidget(name='c_widget'))
        return self.sm


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

上記を実行すると、C のページでボタンを押したときに

this is A Widget

と表示されます。

kv ファイル内の CWidget タグで、AWidget の id を宣言すると、上記が可能になります。

おわりに

今回は、ページ遷移の方法について説明しました。

これで、シングルページアプリケーションではない多機能なアプリを作成することが可能になります。

次回は、ポップアップの表示方法について説明します。

コメント

タイトルとURLをコピーしました