【初心者向け】KivyによるWindowsアプリ作成10 画面遷移の実装方法その1

今回と次回の2回に分けて、ログイン画面でログインボタンを押したときに、次の経費申請画面へ遷移する処理を実装したいと思います。なお、ログイン時のユーザID/パスワード認証については、その後の回に実装することとし、今回はボタンを押すと無条件に画面遷移を行うよう、プログラムを更新していきます。

また、修正後のコード全文は、GitHubにアップしていますのでご参照ください。

GitHub

<スポンサーリンク>

画面遷移の基本的な考え方

さて、プログラムの変更を行う前に、Kivyにおいてどのように画面遷移を実装するのか、基本的な考え方を説明したいと思います。

Kivyで画面遷移を行う場合、ScreenManagerというクラスを使います。このクラスから生成するインスタンスに各画面を登録し、ボタンが押されるなどのイベントが発生した際に、このインスタンスのメソッドを実行することにより画面を切り替えます。

また、各画面はScreenというクラスを継承したサブクラスとして定義します。そして、それらクラスから画面の実体をインスタンスとして生成し、ScreenManagerのインスタンスに登録することによって、各画面をScreenManagerのインスタンスから制御できるようにします。

少し分かりづらいと思いますので、図を書いてみました。

この考え方も活用して、本記事では以下の手順で画面遷移処理を実装していきたいと思います。

①ログイン画面のクラス定義

②ScreenManagerのインスタンス化とログイン画面登録

③経費入力画面(ログイン後の画面)のクラス定義

④ScreenManagerへの経費入力画面登録

⑤ログインボタン押下時の切り替え処理実装

このうち、今回は①、②について説明します。

画面遷移の実装

①ログイン画面のクラス定義

まず、必要なモジュールをインポートしておきましょう。

現在、import文が2行あると思いますが、その下にScreenManagerとScreenのimport文を追加します。

from kivy.app import App
from kivy.core.text import LabelBase, DEFAULT_FONT
from kivy.uix.screenmanager import ScreenManager, Screen #追加

続いて、PythonファイルにScreenクラスを継承した新しいクラス、LoginScreenを定義します。本記事ではLabelBaseの文のすぐ下に、以下のようにクラス定義を入れることにします。

LabelBase.register(DEFAULT_FONT, "ipaexg.ttf")

class LoginScreen(Screen): #このブロックを追加
    pass

さて、現状ではLoginScreenクラスの内部は何も定義されていないため、仮にこのScreenを表示したところで当然何も表示されません。

そこで、このクラスにWidgetを登録しましょう。と言っても、一から登録を行わずとも、これまでKvファイル上で作成してきたログイン画面のレイアウトを流用することができます。

まず、現在Kvファイルの中で最も左から記載されている、つまり、インデントなしで記載されているブロックには、以下の4つがあります。

  • <TextInput>:
  • <Label>:
  • <PaddingBoxLayout@BoxLayout>:
  • BoxLayout:

このうち、上の三つはそれぞれ、TextInput Widget、Label Widget、そして、BoxLayoutを継承したPaddingBoxLayout Widgetに対する共通属性を設定する記述です。そして最後の1つが、ログイン画面のレイアウトを定義した記述です。

なお、Pythonファイル側で最初に描画する画面を明示的に指定しない場合、これらインデントなしで記述されているWidgetのうち<>で括られていないものをウインドウに表示します。今回は4つ目のBoxLayoutが該当します。

一方、Pythonファイル側で描画する画面を指定したい場合、対象のWidgetを<>で括ってレイアウトを記述した上で指定します

後ほど、Pythonファイル側でScreenManagerを使い、描画するWidgetを明示的に指定します。ですので、これらも踏まえ、Kvファイルに新たに「<LoginScreen>:」を追加し、その下に既存のBoxLayoutのブロックを字下げ付きで入れることで、LoginScreen Widgetの中身にログイン画面のレイアウトを追加します。

<LoginScreen>: #追加
    BoxLayout: #既存のブロック内容全てを字下げ
        orientation: "vertical"

#省略

                Button:
                    text: "ログイン"
                        color: 1, 1, 1, 1

これで、ログイン画面の定義は完了です。

②ScreenManagerのインスタンス化とログイン画面登録

続いてScreenManagerの設定に移りましょう。

まずは冒頭の図に示した通り、ScreenManagerのインスタンス化を行います。

Pythonファイル内の、LabelBaseのすぐ下あたりに1行追加しておきましょう。

LabelBase.register(DEFAULT_FONT, "ipaexg.ttf")
sm = ScreenManager() #追加

追加した行は、ScreenManagerのインスタンスを生成して、それをsmという変数に入れるという処理を表しています。

次に、アプリケーション起動時、具体的に言うと、ExpenseAppのrunメソッドが呼び出されたタイミングで、ScreenManagerインスタンスにログイン画面を登録する処理を追加します。

runメソッドが呼び出されるタイミングで処理を実行させたい場合は、元のクラス内に「build」というメソッドを定義し、その中に処理を記述します

Pythonファイル上のExpenseAppクラス内には現在passとだけ記述されていますが、それを以下のようにbuildメソッドに置き換えて下さい。

class ExpenseApp(App):
    def build(self): #passからこのメソッドに置き換え
        sm.add_widget(LoginScreen(name="login"))
        return sm

追加されたbuildメソッドの中身ですが、「LoginScreen(name=”login”)」でLoginScreenクラスを「login」という名称でインスタンス化の上、そのインスタンスをsmに登録しています。

なお、smが画面を切り替える際には、この「login」のような名称を使って切り替え先の画面を指定することができます。

プログラム実行

では、ここまでの作業が終わりましたら、一旦プログラムを実行してみましょう。

前回までと全く同じ画面が表示されれば、ここまでのプログラム修正は成功です。

終わりに

今回は画面遷移の実装(の事前準備)ということで、遷移の前提となるScreenクラスとScreenManagerクラスを利用して、これまで作成したものと全く同様のログイン画面が表示されるようにしました。

次回は今回の実装内容を土台として、ログインボタンを押すことにより経費入力画面に遷移する処理を実装していきたいと思います。

<スポンサーリンク>

シェアする

フォローする