Kivy入門(version1系)
目次
1 概要
- Pythonのライブラリ
- クロスプラットフォームの開発環境
- Kivy + buildozer で Androidアプリを作ってみる
- 環境は Ubuntu version 20.04ベースで行う(Dockerを利用すれば、Dockerを利用できる他のプラットフォームでも同じ手順で行える)
2 関連リンク
- Kivy doc (英語 新しいバージョン)https://kivy.org/doc/stable/
- Kivy doc 日本語訳 https://pyky.github.io/kivy-doc-ja/
- Kivy Crash Course 説明 https://pyky.github.io/kivy-doc-ja/tutorials/crashcourse.html
- Kivy Crash Course
- pngを読み込み、アニメーション例 https://github.com/FutureTechCity/KivyAnimation
- サンプルコード https://github.com/tito/android-demo
- pyjniusを利用する例 https://github.com/tito/android-demo/blob/master/main.py
- 他のKivyのTutorial動画(英語) https://www.youtube.com/watch?v=bMHK6NDVlCM&list=PLzMcBGfZo4-kSJVMyYeOQ8CXJ3z1k7gHn
- kivy/python-for-android https://github.com/kivy/python-for-android/tree/master
- サポートされているパッケージ(Android用) https://github.com/kivy/python-for-android/tree/master/pythonforandroid/recipes
2.1 使うかもしれないパッケージ
- access Java classes as Python classes https://github.com/kivy/pyjnius
- a platform-independent api to use features commonly found on various platforms https://github.com/kivy/plyer
- plyer doc https://plyer.readthedocs.io/en/latest/
- buildozer https://github.com/kivy/buildozer
- 古いバージョンになるが、DockerのHubにイメージありhttps://hub.docker.com/r/kivy/buildozer
3 インストール
3.1 以下の操作を行っている動画
3.2 kivyのUbuntu20.04へのインストール手順
- 手順の確認はDockerのUbuntu 20.04を利用した
- 以下の手順で共有ディレクトリを作成し、Dockerは1000のuidのユーザーで行った
sudo mkdir /work/kivy sudo chown 1000.1000 /work/kivy/
- 起動は以下のコマンドで行った
docker run -it --rm -v /work/kivy:/home/ ubuntu:20.04
3.3 手順
3.3.1 必要パッケージのインストール
apt update apt install python3-kivy
- 一般ユーザーで以下を行う場合は 以下のように先頭に sudoをつける
sudo apt update sudo apt install python3-kivy
4 空のApp作成
4.1 以下の説明を行っている動画
4.2 空のApp作成手順
- tutorial001.py というファイル名で以下内容のファイル作成
from kivy.app import App class HelloWorldApp(App): pass if __name__ == '__main__': HelloWorldApp().run()
4.2.1 実行
python3 tutorial002_helloworld.py
4.3 この章のまとめ
- 空のアプリ作成
5 サンプル用のHello Worldプログラム作成(Label利用)
5.1 以下の説明を行っている動画
5.2 HelloWorld
- tutorial002_helloworld.py というファイル名で以下内容のファイル作成
from kivy.app import App from kivy.uix.label import Label class HelloWorldApp(App): def build(self): return Label(text='Hello World!') if __name__ == '__main__': HelloWorldApp().run()
5.2.1 実行
python3 tutorial002_helloworld.py
5.3 この章のまとめ
- Labelを利用して、Hello World作成
6 BoxLayout
6.1 以下の説明を行っている動画
6.2 関係する文書
6.2.1 Layout関係
- https://kivy.org/doc/stable/guide/widgets.html
- https://kivy.org/doc/stable/api-kivy.uix.floatlayout.html
- https://kivy.org/doc/stable/api-kivy.uix.boxlayout.html
- https://kivy.org/doc/stable/api-kivy.uix.gridlayout.html
- https://kivy.org/doc/stable/api-kivy.uix.stacklayout.html
- https://kivy.org/doc/stable/api-kivy.uix.relativelayout.html
- https://kivy.org/doc/stable/api-kivy.uix.anchorlayout.html
6.3 BoxLayout利用
- tutorial003_boxlayout.py というファイル名で以下内容のファイル作成
from kivy.app import App from kivy.uix.label import Label from kivy.uix.boxlayout import BoxLayout class HelloWorldApp(App): def build(self): b = BoxLayout(orientation="vertical") l1 = Label(text='Hello',font_size=150) l2 = Label(text='World',font_size=150) b.add_widget(l1) b.add_widget(l2) return b if __name__ == '__main__': HelloWorldApp().run()
6.3.1 実行
python3 tutorial003_boxlayout.py
6.4 この章のまとめ
- 部品を良い感じで並べてくれるツールの内BoxLayoutを使ってみた
7 Module: kivy.lang.builder
7.1 以下の説明を行っている動画
7.2 関係する文書
7.2.1 部品関係
7.2.2 Layout関係
- https://kivy.org/doc/stable/guide/widgets.html
- https://kivy.org/doc/stable/api-kivy.uix.floatlayout.html
- https://kivy.org/doc/stable/api-kivy.uix.boxlayout.html
- https://kivy.org/doc/stable/api-kivy.uix.gridlayout.html
- https://kivy.org/doc/stable/api-kivy.uix.stacklayout.html
- https://kivy.org/doc/stable/api-kivy.uix.relativelayout.html
- https://kivy.org/doc/stable/api-kivy.uix.anchorlayout.html
7.3 Builder 利用
- tutorial004_builder.py というファイル名で以下内容のファイル作成
from kivy.app import App from kivy.uix.label import Label from kivy.uix.boxlayout import BoxLayout from kivy.lang.builder import Builder kv=''' BoxLayout: orientation: 'vertical' Label: text: 'Hello' font_size: 150 Label: text: 'World' font_size: 150 ''' class HelloWorldApp(App): def build(self): return Builder.load_string(kv) if __name__ == '__main__': HelloWorldApp().run()
7.3.1 実行
python3 tutorial004_builder.py
7.4 この章のまとめ
- builderを利用して、kivy言語を利用
8 Kivy言語の利用(外部ファイル)
8.1 以下の説明を行っている動画
8.2 関係する文書
8.2.1 部品関係
8.2.2 Layout関係
- https://kivy.org/doc/stable/guide/widgets.html
- https://kivy.org/doc/stable/api-kivy.uix.floatlayout.html
- https://kivy.org/doc/stable/api-kivy.uix.boxlayout.html
- https://kivy.org/doc/stable/api-kivy.uix.gridlayout.html
- https://kivy.org/doc/stable/api-kivy.uix.stacklayout.html
- https://kivy.org/doc/stable/api-kivy.uix.relativelayout.html
- https://kivy.org/doc/stable/api-kivy.uix.anchorlayout.html
8.3 Kivy言語外部ファイルを利用
8.3.1 tutorial005_kivy.py というファイル名で以下内容のファイル作成
from kivy.app import App from kivy.uix.label import Label from kivy.uix.boxlayout import BoxLayout #from kivy.uix.widget import Widget #from kivy.lang.builder import Builder class HelloWorld(BoxLayout): pass class Tutorial005App(App): def build(self): return HelloWorld() if __name__ == '__main__': Tutorial005App().run()
8.3.2 tutorial005.kv ファイルを以下の内容で作成
- ファイル名はAppを継承したクラス名の最後のAppを除いた物が自動で検索される
- 例 今回だと Tutorial005App から tutorial005.kv
- 例 TutorialApp なら tutorial.kv
<HelloWorld>: orientation: 'vertical' Label: text: 'Hello' font_size: 150 Label: text: 'World' font_size: 150
8.3.3 実行
python3 tutorial005_builder.py
8.4 この章のまとめ
- 外部ファイルで、kivy言語を利用
9 Module: kivy.uix.button
9.1 以下の説明を行っている動画
9.2 関係する文書
9.2.1 Builder
9.2.2 部品関係
9.2.3 Layout関係
- https://kivy.org/doc/stable/guide/widgets.html
- https://kivy.org/doc/stable/api-kivy.uix.floatlayout.html
- https://kivy.org/doc/stable/api-kivy.uix.boxlayout.html
- https://kivy.org/doc/stable/api-kivy.uix.gridlayout.html
- https://kivy.org/doc/stable/api-kivy.uix.stacklayout.html
- https://kivy.org/doc/stable/api-kivy.uix.relativelayout.html
- https://kivy.org/doc/stable/api-kivy.uix.anchorlayout.html
9.3 buttonを利用する手順例
9.3.1 tutorial006.py というファイル名で以下内容のファイル作成
- on_release でボタン押して離した時にイベント発生する記述を行う
from kivy.app import App from kivy.uix.label import Label from kivy.uix.boxlayout import BoxLayout from kivy.lang.builder import Builder import random kv=''' <HelloWorld> orientation: 'vertical' Label: id: label1 text: 'Hello' font_size: 150 Button: text: 'Change Color' font_size: 80 on_release: root.changeColor() ''' Builder.load_string(kv) class HelloWorld(BoxLayout): def changeColor(self): print("changeColor") for key, val in self.ids.items(): print("key={0}, val={1}".format(key, val)) print(self.ids) mylabel=self.ids['label1'] mylabel.color=[random.random(),random.random(),random.random(),1] class HelloWorldApp(App): def build(self): return HelloWorld() #return Builder.load_string(kv) if __name__ == '__main__': HelloWorldApp().run()
9.3.2 実行
- Ubuntuでは pythonではなくpython3の必要あるケースあり
python tutorial006.py
9.3.3 tutorial006-2.py というファイル名で以下内容のファイル作成
- kivy言語側で、クリックイベントの処理記述
- kivy言語側で、randomモジュール読み込み
from kivy.app import App from kivy.uix.label import Label from kivy.uix.boxlayout import BoxLayout from kivy.lang.builder import Builder import random kv=''' #:import random random <HelloWorld> orientation: 'vertical' Label: id: label1 text: 'Hello' font_size: 150 Button: text: 'Change Color' font_size: 80 on_release: root.ids['label1'].color=[random.random(),random.random(),random.random(),1] ''' Builder.load_string(kv) class HelloWorld(BoxLayout): pass class HelloWorldApp(App): def build(self): return HelloWorld() #return Builder.load_string(kv) if __name__ == '__main__': HelloWorldApp().run()
9.3.4 実行
- Ubuntuでは pythonではなくpython3の必要あるケースあり
python tutorial006-2.py
9.4 この章のまとめ
- Module: kivy.uix.buttonを使ってみた
- ボタンを押して離した時にイベント発生する処理を書いた
10 Module: kivy.uix.textinputを利用して足し算アプリ作成
10.1 以下の説明を行っている動画
10.2 関係する文書
10.2.1 Builder
10.2.2 部品関係
10.2.3 Layout関係
- https://kivy.org/doc/stable/guide/widgets.html
- https://kivy.org/doc/stable/api-kivy.uix.floatlayout.html
- https://kivy.org/doc/stable/api-kivy.uix.boxlayout.html
- https://kivy.org/doc/stable/api-kivy.uix.gridlayout.html
- https://kivy.org/doc/stable/api-kivy.uix.stacklayout.html
- https://kivy.org/doc/stable/api-kivy.uix.relativelayout.html
- https://kivy.org/doc/stable/api-kivy.uix.anchorlayout.html
10.3 Module: kivy.uix.textinputを利用して足し算アプリ作成 手順
10.3.1 tutorial007.py というファイル名で以下内容のファイル作成
- input_filterで整数のみ入力可能にしてある
from kivy.app import App from kivy.uix.label import Label from kivy.uix.boxlayout import BoxLayout from kivy.uix.textinput import TextInput from kivy.lang.builder import Builder import random # https://kivy.org/doc/stable/api-kivy.uix.textinput.html kv=''' #:import random random <HelloWorld> orientation: 'vertical' TextInput: id: textinput1 font_size: 150 input_filter: 'int' text: '1' TextInput: id: textinput2 font_size: 150 input_filter: 'int' text: '1' Label: id: label1 text: '' font_size: 150 Button: text: 'calc add' font_size: 80 on_release: root.ids['label1'].text=str(int(root.ids['textinput1'].text)+int(root.ids['textinput2'].text)) ''' Builder.load_string(kv) class HelloWorld(BoxLayout): pass class HelloWorldApp(App): def build(self): return HelloWorld() #return Builder.load_string(kv) if __name__ == '__main__': HelloWorldApp().run()
10.3.2 実行
python3 tutorial007.py
10.4 この章のまとめ
- Module: kivy.uix.textinputの基本的な使い方紹介
- Module: kivy.uix.textinputを利用して足し算アプリ作成
11 設定を行う機能
11.1 以下の説明を行っている動画
11.2 関係する文書
11.2.1 Builder
11.2.2 部品関係
11.2.3 Layout関係
- https://kivy.org/doc/stable/guide/widgets.html
- https://kivy.org/doc/stable/api-kivy.uix.floatlayout.html
- https://kivy.org/doc/stable/api-kivy.uix.boxlayout.html
- https://kivy.org/doc/stable/api-kivy.uix.gridlayout.html
- https://kivy.org/doc/stable/api-kivy.uix.stacklayout.html
- https://kivy.org/doc/stable/api-kivy.uix.relativelayout.html
- https://kivy.org/doc/stable/api-kivy.uix.anchorlayout.html
11.3 設定を行う機能の利用手順
11.3.1 tutorial008.py というファイル名で以下内容のファイル作成
- ホームディレクトリの .kivy/config.ini というファイルが設定を変更すると更新される
- app.open_settings() でセッティング画面が表示される
from kivy.app import App from kivy.uix.label import Label from kivy.uix.boxlayout import BoxLayout from kivy.uix.textinput import TextInput from kivy.lang.builder import Builder import random kv=''' #:import random random <MyAdd> orientation: 'vertical' TextInput: id: textinput1 font_size: 100 input_filter: 'int' text: '1' TextInput: id: textinput2 font_size: 100 input_filter: 'int' text: '1' Label: id: label1 text: '' font_size: 100 Button: text: 'calc add' font_size: 80 on_release: root.ids['label1'].text=str(int(root.ids['textinput1'].text)+int(root.ids['textinput2'].text)) Button: text: 'setting' font_size: 80 on_release: app.open_settings() ''' Builder.load_string(kv) class MyAdd(BoxLayout): pass class HelloWorldApp(App): def build(self): return MyAdd() #return Builder.load_string(kv) if __name__ == '__main__': HelloWorldApp().run()
11.3.2 実行
python3 tutorial008.py
11.3.3 tutorial008-2.py というファイル名で以下内容のファイル作成
- ホームディレクトリの .kivy/config.ini というファイルが設定を変更すると更新される
- app.open_settings() でセッティング画面が表示される
- self.settings_cls=SettingsWithSidebar を追加すると横にメニューが追加
- self.use_kivy_settings=False の行の#を外して有効化すると、元々のメニューは選択できなくなる
- 独自メニュー追加
from kivy.app import App from kivy.uix.label import Label from kivy.uix.boxlayout import BoxLayout from kivy.uix.textinput import TextInput from kivy.uix.settings import SettingsWithSidebar from kivy.lang.builder import Builder import json import random Builder.load_string(''' #:import random random <MyAdd> orientation: 'vertical' TextInput: id: textinput1 font_size: 100 input_filter: 'int' text: '1' TextInput: id: textinput2 font_size: 100 input_filter: 'int' text: '1' Label: id: label1 text: '' font_size: 100 Button: text: 'calc add' font_size: 80 on_release: root.ids['label1'].text=str(int(root.ids['textinput1'].text)+int(root.ids['textinput2'].text)) Button: text: 'setting' font_size: 80 on_release: app.open_settings() ''') settings_json=json.dumps([ {'type': 'title', 'title': 'example title'}, {'type': 'bool', 'title': 'a boolean setting', 'desc': 'Boolean description text', 'section':'example', 'key':'boolexample'}, {'type': 'numeric', 'title': 'a numerical setting', 'desc': 'Numeric description text', 'section':'example', 'key':'numericalexample'}, {'type': 'options', 'title': 'a options setting', 'desc': 'Option description text', 'section':'example', 'key':'optionsexample', 'options':['1','2','3']}, {'type': 'string', 'title': 'a string setting', 'desc': 'String description text', 'section':'example', 'key':'stringexample'}, {'type': 'path', 'title': 'a path setting', 'desc': 'Path description text', 'section':'example', 'key':'pathexample'}, ]) class MyAdd(BoxLayout): pass class HelloWorldApp(App): def build(self): self.settings_cls=SettingsWithSidebar # self.use_kivy_settings=False setting1 = self.config.get('example', 'optionsexample') print(self.config.items('example')) return MyAdd() #return Builder.load_string(kv) def build_config(self, config): config.setdefaults('example', { 'boolexample':True, 'numericalexample':1, 'optionsexample':'3', 'stringexample':'abc', 'pathexample':'./', }) def build_settings(self, settings): settings.add_json_panel('test', self.config, data=settings_json) def on_config_change(self, config, section, key, value): print([config, section, key, value]) if __name__ == '__main__': HelloWorldApp().run()
11.3.4 実行
python3 tutorial008-2.py
11.4 この章のまとめ
- ベースはCrash Courseの13番目の動画を参考に作成
- 設定関係の説明を行った
- 独自メニューの追加方法も紹介
12 スクリーンマネジャー(画面切替)
12.1 以下の説明を行っている動画
12.2 関係する文書
12.2.1 Builder
12.2.2 部品関係
12.2.3 Layout関係
- https://kivy.org/doc/stable/guide/widgets.html
- https://kivy.org/doc/stable/api-kivy.uix.floatlayout.html
- https://kivy.org/doc/stable/api-kivy.uix.boxlayout.html
- https://kivy.org/doc/stable/api-kivy.uix.gridlayout.html
- https://kivy.org/doc/stable/api-kivy.uix.stacklayout.html
- https://kivy.org/doc/stable/api-kivy.uix.relativelayout.html
- https://kivy.org/doc/stable/api-kivy.uix.anchorlayout.html
12.2.4 設定関係の文書
12.3 スクリーンマネジャー(画面切替) 手順
12.3.1 tutorial009.py というファイル名で以下内容のファイル作成
- スクリーンマネジャーはScreenManagerを継承
- 切り替える画面はScreenを継承
- クラスの定義はkivy言語の読み込み前に行わないとエラーになっていた
- kivy.uix.screenmanager.FadeTransitionをkivy言語側でインポート
- transition: FadeTransition() の 先頭の#をはずすと、画面切替の様子が変更になる
from kivy.app import App from kivy.uix.label import Label from kivy.uix.boxlayout import BoxLayout from kivy.uix.textinput import TextInput from kivy.uix.settings import SettingsWithSidebar from kivy.lang.builder import Builder from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition import json import random class MyScreenManager(ScreenManager): pass class MyAdd(Screen): pass class MySub(Screen): pass root_widget = Builder.load_string(''' #:import random random #:import FadeTransition kivy.uix.screenmanager.FadeTransition MyScreenManager: #transition: FadeTransition() MyAdd: MySub: <MyAdd> name : 'MyAdd' BoxLayout: orientation: 'vertical' TextInput: id: textinput1 font_size: 100 input_filter: 'int' text: '1' TextInput: id: textinput2 font_size: 100 input_filter: 'int' text: '1' Label: id: label1 text: '' font_size: 100 Button: text: 'calc add' font_size: 80 on_release: root.ids['label1'].text=str(int(root.ids['textinput1'].text)+int(root.ids['textinput2'].text)) Button: text: 'setting' font_size: 80 on_release: app.open_settings() Button: text: 'go to sub' font_size: 80 on_release: app.root.current = 'MySub' <MySub> name : 'MySub' BoxLayout: orientation: 'vertical' TextInput: id: textinput1 font_size: 100 input_filter: 'int' text: '1' TextInput: id: textinput2 font_size: 100 input_filter: 'int' text: '1' Label: id: label1 text: '' font_size: 100 Button: text: 'calc sub' font_size: 80 on_release: root.ids['label1'].text=str(int(root.ids['textinput1'].text)-int(root.ids['textinput2'].text)) Button: text: 'setting' font_size: 80 on_release: app.open_settings() Button: text: 'go to add' font_size: 80 on_release: app.root.current = 'MyAdd' ''') # ここで定義するとエラーに #class MyScreenManager(ScreenManager): # pass # #class MyAdd(Screen): # pass # #class MySub(Screen): # pass # settings_json=json.dumps([ {'type': 'title', 'title': 'example title'}, {'type': 'bool', 'title': 'a boolean setting', 'desc': 'Boolean description text', 'section':'example', 'key':'boolexample'}, {'type': 'numeric', 'title': 'a numerical setting', 'desc': 'Numeric description text', 'section':'example', 'key':'numericalexample'}, {'type': 'options', 'title': 'a options setting', 'desc': 'Option description text', 'section':'example', 'key':'optionsexample', 'options':['1','2','3']}, {'type': 'string', 'title': 'a string setting', 'desc': 'String description text', 'section':'example', 'key':'stringexample'}, {'type': 'path', 'title': 'a path setting', 'desc': 'Path description text', 'section':'example', 'key':'pathexample'}, ]) class HelloWorldApp(App): def build(self): self.settings_cls=SettingsWithSidebar self.use_kivy_settings=False setting1 = self.config.get('example', 'optionsexample') print(self.config.items('example')) return root_widget #return Builder.load_string(kv) def build_config(self, config): config.setdefaults('example', { 'boolexample':True, 'numericalexample':1, 'optionsexample':'3', 'stringexample':'abc', 'pathexample':'./', }) def build_settings(self, settings): settings.add_json_panel('test', self.config, data=settings_json) def on_config_change(self, config, section, key, value): print([config, section, key, value]) if __name__ == '__main__': HelloWorldApp().run()
12.3.2 実行
python3 tutorial009.py
12.4 この章のまとめ
- ベースはCrash Courseの14番目の動画https://www.youtube.com/watch?v=xx-NLOg6x8o&list=PLdNh1e1kmiPP4YApJm8ENK2yMlwF1_edq&index=14を参考に作成
- 画面切替機能の利用方法を紹介
13 今後
- 今後も文書追加していきます。
14 この文書のチェンジログ
- 2020/08/13 初版
- 2020/08/14 Module: kivy.lang.builder の章, Module: kivy.lang.builderの章, Kivy言語の利用(外部ファイル) の章追加
- 2020/08/14 Module: kivy.uix.buttonの章, Module: kivy.uix.textinputを利用して足し算アプリ作成 の章, 設定を行う機能 の章, スクリーンマネジャー(画面切替) の章追加
Created: 2020-08-14 金 19:25