くろねこ日記

ソフトウェアに関する技術メモが多いです.

kivyでデスクトップアプリケーション

はじめに

クロスプラットフォームGUIアプリを開発するためのフレームワークにkivyがあります kivyのホームページ

ここ最近,デスクトップアプリケーション開発といえば個人的にkivyを使用することが多くなりました.pythonにはpyQTwxpython,Tkinterなど多くありますが,pyQTはウェブや書籍を参考にできるほど文献が少ないこと,wxpythonの場合は更新がすでに止まっており,採用には至りませんでした.Tkinterを使うことも考えられますが,kivyのほうがスマートフォン上で動作するという違いがあり興味が湧いたのでkivyを使うに至りました.

ここではkivyの基本構成について忘れないようにメモしておきます.

必要なリファレンスについては

kivy documentation

PythonでかんたんiOSアプリプログラミング―Kivyによるマルチタッチアプリケーション制作

を参考にしました.

kivyのインストール

少し前のブログをお読みください kivyをpipからインストールしてみた

本記事ではPythonは2.7.6,kivyのバージョンは1.8を対象に書いております.

kivyの開発

まずはHelloWorld

kivyには様々なウィジェットがあります.そのなかにもラベルと呼ばれるアプリケーション上に文字列を表現するものがあります.ここではラベル上に「HelloWorld」を出力するコードを示します.

from kivy.app import App
from kivy.uix.label import Label

class TestApp(App):
    def build(self):
        return Label(text='Hello World')

TestApp().run()

これだけですね.

from kivy.app import Appについてはアプリのインポート,二行目はラベルのインポートです.

公式サイトのhomepageにも載っていますが,labelとLabelの箇所をそれぞれbutton,Buttonに変更すればボタン上にHelloWorldが表示されます.

pythonでファイルを指定すれば実行できます.

ちょっとまともなGUIアプリ

さて,HelloWorldの例を読むだけではreturnでボタンを返すだけでは面白くないかもしれません. ここでは僕が普段利用しているファイル関係を示しておこうと思います.

以下に基本的なファイル関係を示しておきます.

├── main.py
├── my.kv

main.pyという実行ファイル,my.kvというGUIレイアウトなどを記述するファイルです. メインとなる実行ファイルについてはHelloWorldを表示したようにPythonで処理を記述するものです.

my.kvはkivyにおけるデザイナの位置やIDと呼ばれるGUI部品とコードを紐付けるものを定義するものです.pythonコードで部品を設置しなくてもmy.kvに部品を配置することで,main.pyでは見た目を気にせず処理内容にだけ注力することができます.

また,名前を変更することも可能ですが,初期設定ではmy.kvという名前のファイルを読むように設定されており,そこについてはここでは触れません.

以下に,ボタンを押したらラベルの値に現在時刻を表示するアプリを例にmain.pyとmy.kvの設定や関係を説明していきます..

まずはmy.kvの説明をします.

今回作るアプリはボタンを押したらLabel上に現在時刻を表示するものです. そのため,ウィジェット名とラベル,ボタンをそれぞれ一個づつ配置する必要がありますので配置していきましょう.

まずは,ウィジェット名と任意の名前をラベル・ボタンそれぞれに付けていきましょう.

ここでは

  • ウィジェット名はtimerWidget

  • ラベルの名前はlabeldatetime

  • ボタンの名前はbuttoncount

としました.

それぞれの部品設定を設定を以下に示します.

labeldatetimeの設定

  • id:labeldatetimeval

  • フォントサイズ:50pt

  • 位置(横,縦):(中央,アプリ上部)

  • 初期設定の文字列:「time」

buttoncountの設定

*ID: buttoncountval

*フォントサイズ:50pt

*位置(横,縦):(中央,アプリ上部から下方向に向かって180ピクセル)

*ボタンサイズ(幅,高さ):(140,70)

*設定の文字列:「Click!」

これをkvファイルで表現すると次のようになります.

my.kv

#:kivy 1.8.0

<timerWidget>:
    labeldatetime: labeldatetimeval
    buttoncount: buttoncountval

    #Labeldatetime
    Label:
        id: labeldatetimeval
        font_size: 50
        center_x: (root.width/2)
        top: root.top
        text: 'time'
    #buttoncount
    Button:
        id: buttoncountval
        font_size: 50
        center_x: (root.width/2)
        size: 140,70
        top: root.top-180
        text: 'Click!'

まず一番上で,kivyのバージョンとウィジェット名,部品IDとpythonコードで使用する部品名を紐付けています. あとはそれぞれフォントサイズや位置,部品サイズ,部品の文字列などを定義しているだけです.

次にmain.pyで処理を書いていきましょう.

ここではウィジェットとして定義した部品を操作する箇所です.ボタンが押されたらその都度表示時刻を現在時刻に置きかえるというものです.

main.py

# -*- coding: utf-8 -*-

import kivy
kivy.require('1.8.0')

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
import datetime

class timerWidget(Widget):
    labeldatetime = ObjectProperty(None)
    buttoncount = ObjectProperty(None)

class MyApp(App):

    def buttoncount_clicked(self, src):
        self.root.labeldatetime.text = str(datetime.datetime.now())

    def build(self):
        self.root = timerWidget()
        self.root.buttoncount.bind(on_press=self.buttoncount_clicked)
        return self.root


if __name__ == '__main__':
    MyApp().run()

上から説明するとまずは,kivyのバージョン,アプリ起動に必要なAppとWidget,kvファイルで定義したWidgetを取りだすObjectProperty,現在時刻を扱うdatetimeをインポートしています.

class timerWidget(Widget)ではmy.kvで紐付けられている部品を取りだしたり描画する箇所です. my.kvで定義した変数を左辺に置いて右辺にはObjectProperty(None)と記述するだけです.

class MyApp(App)では起動に必要な準備やイベントハンドラと呼ばれるボタンをクリックしたときの処理などを書いていきます.

timerWidgetを生成. つぎにボタンをクリックしたときの処理をbind(on_press= )で定義しています. 最後にウィジェット自体を返すだけです.

次にMyApp().run()で実行です

以下に実行画面を示します

実行画面(クリック時)

f:id:kuroneko0208:20140315162302p:plain

まとめ

簡単なkivyの使い方をまとめてみました. 必要な部品などの配置はkvファイルが担当し,部品を操作するのはmain.pyです.

kivyにはもちろんこれ以外にもたくさんの部品があります.

また形には見えない部品もあります.例を挙げれば一定の時間で自動で実行するClockなどです.機会があればその辺についても書きたいと思います.