LoginSignup
11
18

More than 5 years have passed since last update.

Pythonで作るGUIアプリ with kivy kivy語編

Posted at

はじめに

本記事は、PythonのGUI作成ライブラリであるkivyの使い方について解説する記事です。

よろしければ、以前の記事もご参照ください。

Pythonで作るGUIアプリ with kivy 導入編
Pythonで作るGUIアプリ with kivy 環境構築編
Pythonで作るGUIアプリ with kivy 基礎編

kivy Languageについて

前回はじめてのkivyアプリに毛を生やしたヤツでは、下記のようにしてBoxLayoutを使って部品を配置する様子を見ていきました。

# coding:utf-8

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button

class MainScreen(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self.orientation = "vertical"

        btn = Button(text="hello")
        self.add_widget(btn)

        btn2 = Button(text="everyone")
        self.add_widget(btn2)

        btn3 = Button(text="how")
        self.add_widget(btn3)

        btn4 = Button(text="are")
        self.add_widget(btn4)

        btn5 = Button(text="you")
        self.add_widget(btn5)

        btn6 = Button(text="today?")
        self.add_widget(btn6)


class MainApp(App):
    def build(self):
        MS = MainScreen()
        return MS

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

さて、これからここに改造に改造を加えて最高にCOOLなアプリを作っていく訳ですが、勘のいい方はもうお解りの通り、これ、この調子で書いて行くと、コードが凄まじく長くて読み辛いモノになっていきます。

というのも、ボタンを一つ追加するだけでも、

  1. Widgetをインスタンス化
  2. インスタンス化したwidgetのプロパティを変更
  3. add_widget

この作業をひたすら繰り返していく訳です。その際、「このWidget、どのWidgetにaddすれば良いんだっけ…?」「(画面を見ながら)あれ、このボタン、コードで何行目で作ったWidgetだっけ…?」を、ながーーーくてふくざーーーつなコードを逐次読み解きながら改造を加えていく訳です。

正直やっていられませんよね。COOLなアプリを完成させる前に心が折れそうです。

そんな時に登場するのが、kivy languageという、kivy独特の機構です。

これは画面(=Widgetたち)を、ある意味Python風に、ある意味HTML風に、記述するためのツールです。

使い方は実に簡単で、Pythonに慣れていれば、いや慣れていなくても、割りとすぐに理解できるかと思います。早速見てみましょう。

kivy語の基本的な使い方

言葉で説明するよりもコードを見ながらの方が解り易いかと思いますので、まずは何も考えずに動かしてみます。

以前に作ったはじめてのkivyアプリは、下記のようなコードでした。

# coding:utf-8

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button

class MainScreen(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        btn = Button(text="hello")
        self.add_widget(btn)

class MainApp(App):
    def build(self):
        MS = MainScreen()
        return MS

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

これをkivy語を使って書くと、下記のようになります。

# coding:utf-8

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button

from kivy.lang.builder import Builder

Builder.load_string('''
<MainScreen>:
    Button:
        text: "hello"
''')

class MainScreen(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

class MainApp(App):
    def build(self):
        return MainScreen()

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

7~9行目が追加され、ボタンのインスタンス化+add_widgetの部分が無くなっています。

次に、ボタンを1つ追加した版を見てみます。
Builder.load_string(''' ''')で囲まれた部分にご注目ください。

# coding:utf-8

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button

from kivy.lang.builder import Builder

Builder.load_string('''
<MainScreen>:
    Button:
        text: "hello"
    Button:
        text: "everyone"
''')

class MainScreen(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

class MainApp(App):
    def build(self):
        return MainScreen()

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

次に、ボタンの配置を縦方向にしてみます。

# coding:utf-8

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button

from kivy.lang.builder import Builder

Builder.load_string('''
<MainScreen>:
    orientation: "vertical"
    Button:
        text: "hello"
    Button:
        text: "everyone"
''')

class MainScreen(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

class MainApp(App):
    def build(self):
        return MainScreen()

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

最後に、はじめてのkivyアプリに毛を生やしたヤツをkivy語で書いてみます。

# coding:utf-8

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button

from kivy.lang.builder import Builder

Builder.load_string('''
<MainScreen>:
    Button:
        text: "hello"
    Button:
        text: "everyone"
    BoxLayout:
        orientation: "vertical"
        Button:
            text: "how"
        Button:
            text: "are"
        Button:
            text: "you"
    Button:
        text: "today?"
''')

class MainScreen(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

class MainApp(App):
    def build(self):
        return MainScreen()

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

おわかりいただけたでしょうか。

kivy語では上記の様にして、インデントを用いて

  1. Widgetを入れ子にして配置
  2. Widgetのプロパティ設定

する事が可能です。

大文字から始まるモノはWidget、小文字から始まるモノはプロパティとなります。Widgetには2種類の系統(レイアウト系と部品系)ある点については、kivy語で書こうが書くまいが同じ話ですね。

もちろん、kivy語で書く方法と通常通りの方法(インスタンス化・プロパティ設定・add_widgetする方法)は併用する事が可能です。

# coding:utf-8

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button

from kivy.lang.builder import Builder

Builder.load_string('''
<MainScreen>:
    Button:
        text: "hello"
''')

class MainScreen(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        btn = Button(text="everyone")
        self.add_widget(btn)

class MainApp(App):
    def build(self):
        return MainScreen()

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

後々、ボタンをクリックした際に何かWidgetを追加/削除させたりする時には通常通りの方法を使うことの方がむしろ多いので、kivy語での記述と併せて書くことに慣れておくといいかもしれません。

説明が多少前後してしまいますが、kivy語内の< >で囲まれた部分は、その挙動を定義しているクラス名と同一である必要があります。

上記の例では、10行目の<MainScreen>と、15行目のclass MainScreen(BoxLayout):が、ちゃんと同じ名前になっています。つまり、MainAppが立ち上がり、MainScreen()をインスタンス化する際に、書かれたkivy語Builder.load_string(''' ''')を読み込んで、同一の名前のモノがあれば、kivy語を解読して画面を構築する、みたいな流れです。

参考までに、2つのクラスを作ったとき、kivy語側がどんな風になるかを見てみます。

# coding:utf-8

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button

from kivy.lang.builder import Builder

Builder.load_string('''
<MainScreen>:
    orientation: "horizontal"
    Button:
        text: "hello"
    Button:
        text: "everyone"

<SubScreen>:
    orientation: "vertical"
    Button:
        text: "how"
    Button:
        text: "are"
    Button:
        text: "you"
    Button:
        text: "today?"
''')

class MainScreen(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

class SubScreen(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)


class MainApp(App):
    def build(self):
        # hoge = True
        hoge = False

        if hoge:
            return MainScreen()
        else:
            return SubScreen()

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

すごく簡単というか雑な例で恐縮ですが、このようにして複数のWidgetの塊(MainScreenSubScreenのような)をkivy語で定義しておくことも可能です。

このようにkivy語という機構は本当に便利なのですが、その便利さについては実際にガリガリとコードを書き始めた後に実感として湧いてくる類の物かと思いますので、是非ご自身で感じてみて頂ければと思います。

今回はこれにて。次回は、Widgetのサイズや色を操作する方法を見て行きたいと思います。

以上、ありがとうございました。

11
18
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
18