Python3 マスターへの道:その6
前回、最後にお知らせしたように、今回からは、tkinter に変わって kivy を学んでいきたいと思います。ですが、お伝えしたように、当面の目的は、非公式『どうぶつしょうぎ』のプレイ盤を GUI で作成することです。
Kivy をインストールしてみる
Kivy のインストールの仕方は様々あるようで、色々比べて調べましたが、Kivy 公式サイトにあるHomebrew で使った方法で、インストールしました。時間はかかりましたが、無事インストールできたと思います(自信はないなぁ……)。
色々使ってみようと、まずは、実行テストのために、公式サイトにあるコードを実行してみました。
1 import kivy 2 kivy.require('1.11.1') 3 4 from kivy.app import App 5 from kivy.uix.label import Label 6 7 class MyApp(App): 8 9 def build(self): 10 return Label(text='Hello world') 11 12 if __name__ == '__main__': 13 MyApp().run()
しかし、ここで知ったのが、jupyter notebook では、この Kivy は処理できないと……(厳密には、できるが、対応しているわけではないらしい)とにかく、Xcode にコピペして、hello_world.py で保存。そして実行!
$ python3 hello_world.py
ちゃんと表示されました!(ちなみに、壁紙は、MacOS を Catalina にアップデートしたという報告も込めて)
しかし、まだガッツポーズはできません。なぜなら、私がしたのは、ただのコピペ。コードを理解しなければ、学習になってませんよね。
Kivy のコードを理解していく
コードの意味。これが、公式ページに、わかりやすく載っていればいいのですが、もちろん、プログラミング初心者には、理解がなかなか難しい。誰かがこれについて書いていないかと調べてみるものの、やはり、初歩すぎるのか、説明が見つかりませんでした……
ということで、ここからは私のコードの解釈で進めていきます。間違っていたら、教えてください! 絶対ですよ!
とにかく、まずは、部分ごとに分けて理解していくしかありませんね。まずは、
1 import kivy 2 kivy.require('1.11.1')
これは、わかりそうですね。kivy モジュールをインポートして、少なくても必要なバージョン数を指定したという事でしょう。しかし、このモジュール自体は、自分でコードを実行する中では、必要はなさそうですね。
3 from kivy.app import App 4 from kivy.uix.label import Label
この2行では、二つのモジュールからインポートしているみたいですね:kivy.app モジュールと kivy.uix.label モジュール。この2行以降は、これらに基づいているようなので、この二つのモジュールを理解していくことから始めましょう!
kivy.app モジュール
このモジュールからは、App というクラスがインポートされています。このクラスは、アプリケーションを作成するもののように考えておきます。そして、13 行目にもあるのですが、App.run を実行することで、アプリケーションを実行できるのです。
しかし、今回のコードでは、App.run ではなく、MyApp().run になっていますよね。これは、実は、7 行目で、MyApp に App が継承されているからです。つまり、MyApp が App のサブクラスということです。
7 class MyApp(App):
私自身もサブクラスを使う機会が少なかったので、忘れていましたが、サブクラスを作成すると、親クラスのメソッドなどはそのまま使えます。なので、13 行目のコードも理解できますね。
13 MyApp().run()
また、サブクラスでは、親クラスのメソッド再定義することで、オーバーライドすることができるのです。そして、それが、まさに、9, 10 行目で build メソッドに行われています。
9 def build(self): 10 return Label(text='Hello world')
ちなみに、build メソッドは、アプリケーションが実行された時(.run メソッドが使用された際)、その最初に、一度実行されるもののようです。
そして、オーバーライドされる前は、空のようです。実際に、App クラスのまま、実行してみましたが、ウィンドウが表示されただけでした。
ここで、最後に重要なのが、今回の MyApp のように、サブクラスは App で名前が終わらないといけないことです。この理由は、サブクラス名に基づいて、そのサブクラスから App を除いた名義の kv ファイルを探すからです。
なので、プログラムをクラスで分けて書くことで、本元がだらだらと長くなることを防ぐことができます。ちなみに、kv ファイルにおける書式を、kv 言語と呼びます。これについては、次回から学んでいきます。
kivy.uix.label モジュール
こちらの kivy.uix.label モジュールは、ここでは、Lable というメソッドをインポートするために使われています。この Label メソッドは、機能的に、tkinter での Label メソッドに似ていますね。この使い方としては、10 行目のような、書き方のようです。
10' Label(text='Hello world')
書式の変更には、markup という機能を用いる事でできるみたいです。これは、html の書き方に似ていますね。例えば、Hello World に使ってみるとすると、
10' Label(text='[color=FF0000]Hello[/color] [b]world[/b]', markup=True)
といった形式のようです。これを実行すると、
赤文字(#FF0000)の Hello と 太字の world が表示されましたね。最初にしては、上出来ですね。
他にも、先ほど名前を出した kv 言語では、少し異なった書式になっています。しかし、これも次回から、書いていきたいと思います。
__name__ と '__main__' の関係性
という事で、まだ最後に、理解ができていないチュートリアルのコードがありますよね。そうです。次の 12 行目です。
12 if __name__ == '__main__':
if 文だからわかりそうですが、__name__ もわかりませんし、__main__ もなんだか……
と、このサイトを主に読んで、理解がなんとかできました。ありがとうございます。
まず、__name__ には、そのファイル自体を指しています。そして、'__main__' は実行されているスコープ名(メインスコープ名)を指します。なので、この二つが同じであるということは、そのファイルが実行されているということになりそうです。
逆に、もし、あるファイルがただインポートされているだけなら、__name__ と実際に実行している '__main__' は一致しません。なので、インポートの際に、コードが実行されてしまうのを防ぐ役割として、この if 文は存在しているのです。
なので、今回のように、この py ファイルを実行しているので、13 行目のアプリケーションの実行文はしっかり実行されていましたね。
最後に
このように、今回は、kivy 初回にもかかわらず、なかなか濃厚な学習でしたね。tkinter と同じ GUI のシステムでも、根本的に違うことがわかりました。これからは、似たところも増えるのかな?Kivy のわかりやすい情報は、限られているので、実際にコードを書く前に、今回のように、現存するコードを理解していくところから、初めていきたいと思っています。説明がうまく伝わっていると嬉しいです。
次回は kv 言語についても触れていきます。それでは、また!
前回:Tkinter フレームの使い方のウィジェットの構図を考える
次回:kv 言語の書き方・使い方を学ぶ