Python kivyで画面切り替えの最小構成




# はじめに

[Python Kivyの使い方②　～電卓を作成する～ - Qiita](https://qiita.com/dario_okazaki/items/910abf09344a60dd7823#%E3%82%B3%E3%83%BC%E3%83%89)

を写経しまして画面切り替えは動いたのですが、より理解を深めるために最小構成をゼロから作ってみます。




# 想定環境

- Windows 10（Pythonでkivyなので他OSでもだいたい同等です）
- Python 3.6.5
- pip 18.0
- kivy 1.10.0
- Nuitka 0.5.30（基本的には出てきませんが、実行ファイル形式出力が可能な状態を維持します）



# Pythonコード

基本的には

[Python Kivyの使い方②　～電卓を作成する～ - Qiita](https://qiita.com/dario_okazaki/items/910abf09344a60dd7823#%E3%82%B3%E3%83%BC%E3%83%89)

のものをベースに使いつつ、拙著

[PythonのKivyで音楽プレイヤー - Qiita](https://qiita.com/mkgask/items/dcd0f173998168fe5614#%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%90%8D%E3%81%AE%E5%AF%BE%E5%BF%9C)

で書いた日本語フォント表示対応を入れてあります。
MacやLinuxではresource_add_pathで読み込むパスとLabelBase.registerで指定するフォント名を変えれば動くと思いますが、筆者未確認です。

```python:main.py
# -*- coding: utf-8 -*
import os
import kivy

from kivy.app import App
from kivy.core.window import Window
from kivy.factory import Factory

from kivy.uix.boxlayout import BoxLayout

# 日本語フォント表示対応
from kivy.core.text import LabelBase, DEFAULT_FONT
from kivy.resources import resource_add_path

resource_add_path('{}\\{}'.format(os.environ['SYSTEMROOT'], 'Fonts'))
LabelBase.register(DEFAULT_FONT, 'MSGOTHIC.ttc')

# kvファイルを画面ごとに分離してバラで読み込む
from kivy.lang import Builder

Builder.load_file('window1.kv')
Builder.load_file('window2.kv')



class MainRoot(BoxLayout):
    window1 = None
    window2 = None

    def __init__(self, **kwargs):
        # 起動時に各画面を作成して使い回す
        self.window1 = Factory.Window1()
        self.window2 = Factory.Window2()
        super(MainRoot, self).__init__(**kwargs)

    def change_disp(self):
        self.clear_widgets()
        self.add_widget(self.window1)

    def change_disp2(self):
        self.clear_widgets()
        self.add_widget(self.window2)

class MainApp(App): 
    def __init__(self, **kwargs):
        super(MainApp, self).__init__(**kwargs)
        self.title = '画面切り替えテスト'
    pass

if __name__ == "__main__":
    MainApp().run()
```

kvファイルをバラして読み込んでいるところと、起動時にFactoryで両ウィンドウを作成してしまって、その後は使いまわしているところがポイントです。



# kvファイル

## main.kv

```yml:main.kv
MainRoot

<MainRoot>
    Window1
```

MainRootで読み込むウィジェットを切り替えることで、最初に表示するウィンドウの選択が出来ます。



## window1.kv

```yml:window1.kv
<Window1@BoxLayout>
    orientation: "vertical"

    ActionBar:
        ActionView:

            ActionPrevious:
                title: 'ウィンドウ1'
                with_previous: False

            ActionButton:
                text: '切り替え'
                on_press: print("change disp window 1"); app.root.change_disp2()

    BoxLayout:
        Label:
            text: '画面1'
```



## window2.kv

```yml:window2.kv
<Window2@BoxLayout>
    orientation: "vertical"

    ActionBar:
        ActionView:

            ActionPrevious:
                title: 'ウィンドウ2'
                with_previous: False

            ActionButton:
                text: '切り替え'
                on_press: print("change disp window 2"); app.root.change_disp()

    BoxLayout:
        Label:
            text: '画面2'
```

kvファイルをバラしてあるので、画面ごとにファイルを作成出来ます。

一つ一つのファイルが小さくて短いので、すっきりしてだいぶ分かりやすいかと思います。

![clipboard01](https://user-images.githubusercontent.com/8291395/44616352-4667e500-a889-11e8-9ad8-31d1a1a0d458.jpg)

![clipboard02](https://user-images.githubusercontent.com/8291395/44616355-4f58b680-a889-11e8-925f-102c3f4b7c40.jpg)