Kivy
マルチタッチ対応のクロスプラットフォームGUIフレームワーク。独自のレンダリングエンジンによりモバイル・デスクトップ・Web間での一貫したUI体験を提供。ゲームやインタラクティブアプリケーション開発に特化。
GitHub概要
kivy/kivy
Open source UI framework written in Python, running on Windows, Linux, macOS, Android and iOS
ホームページ:https://kivy.org
スター18,475
ウォッチ603
フォーク3,128
作成日:2010年11月3日
言語:Python
ライセンス:MIT License
トピックス
androidappioskivylinuxmacospythonuiwindows
スター履歴
データ取得日時: 2025/7/16 08:43
フレームワーク
Kivy
概要
Kivyは、Pythonで書かれたオープンソースのクロスプラットフォームUIフレームワークです。Windows、Linux、macOS、Android、iOSで動作し、タッチ操作に対応したグラフィカルアプリケーションを開発できます。自然なマルチタッチ操作と豊富なUIウィジェットを提供します。
詳細
Kivyは、2025年現在でもPythonクロスプラットフォーム開発の有力な選択肢として継続的に進化しています。特にタッチ操作が重要なデスクトップアプリケーション、キオスクアプリケーション、教育用アプリケーション分野で強みを発揮しています。
OpenGLベースの描画エンジンにより高速なグラフィックス描画を実現し、独自のKV言語によるレイアウト記述、豊富なウィジェットライブラリ、アニメーション機能、マルチタッチジェスチャ認識など、現代的なUIアプリケーション開発に必要な機能を包括的に提供しています。
PyInstaller、Buildozer、p4aなどのパッケージングツールとの統合により、各プラットフォーム向けの実行ファイルやアプリパッケージの作成も容易です。ゲーム開発、教育用ソフトウェア、産業用制御パネル、デジタルサイネージなど、様々な分野で採用されています。
メリット・デメリット
メリット
- 真のクロスプラットフォーム: デスクトップとモバイルの両方に対応
- タッチファースト設計: 自然なマルチタッチとジェスチャ操作
- OpenGL描画: 高速なグラフィックス描画とアニメーション
- KV言語: 直感的で保守しやすいレイアウト記述
- 豊富なウィジェット: 豊富なUIコンポーネントライブラリ
- Pythonの生産性: Pythonの学習しやすさと豊富なライブラリ
- オープンソース: MIT ライセンスで商用利用可能
- アクティブコミュニティ: 継続的な開発とサポート
デメリット
- ネイティブ外観: プラットフォーム固有のネイティブ外観ではない
- 学習コスト: Kivy特有の概念とKV言語の習得が必要
- アプリサイズ: OpenGL依存によりバイナリサイズが大きくなる
- メモリ使用量: リッチなグラフィックスによりメモリ消費が多い
- モバイル制約: iOS/Android向けパッケージング作業が複雑
- ドキュメント: 一部ドキュメントの内容が古い場合がある
主要リンク
- Kivy公式サイト
- Kivy公式ドキュメント
- Kivy GitHub リポジトリ
- Kivy Garden(アドオンウィジェット)
- KivyMD(Material Design)
- Buildozer(Android/iOS パッケージング)
書き方の例
Hello Worldアプリケーション
# hello_world.py
import kivy
kivy.require('2.1.0')
from kivy.app import App
from kivy.uix.label import Label
class MyApp(App):
def build(self):
return Label(text='Hello, Kivy!')
if __name__ == '__main__':
MyApp().run()
ログイン画面(Python + KV言語)
# login_app.py
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
class LoginScreen(GridLayout):
def __init__(self, **kwargs):
super(LoginScreen, self).__init__(**kwargs)
self.cols = 2
# ユーザー名入力
self.add_widget(Label(text='ユーザー名'))
self.username = TextInput(multiline=False)
self.add_widget(self.username)
# パスワード入力
self.add_widget(Label(text='パスワード'))
self.password = TextInput(password=True, multiline=False)
self.add_widget(self.password)
# ログインボタン
self.add_widget(Label(text='')) # 空のセル
login_btn = Button(text='ログイン')
login_btn.bind(on_press=self.on_login)
self.add_widget(login_btn)
def on_login(self, instance):
print(f'ユーザー名: {self.username.text}')
print(f'パスワード: {self.password.text}')
class LoginApp(App):
def build(self):
return LoginScreen()
if __name__ == '__main__':
LoginApp().run()
ペイントアプリケーション
# paint_app.py
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.graphics import Color, Ellipse, Line
from random import random
class PaintWidget(Widget):
def on_touch_down(self, touch):
with self.canvas:
# HSVカラーモードで一貫した明度の色を生成
color = (random(), 1., 1.)
Color(*color, mode='hsv')
# タッチポイントに円を描画
d = 30.
Ellipse(pos=(touch.x - d/2, touch.y - d/2), size=(d, d))
# 線描画の開始
touch.ud['line'] = Line(points=(touch.x, touch.y))
def on_touch_move(self, touch):
# タッチ移動で線を延長
if 'line' in touch.ud:
touch.ud['line'].points += [touch.x, touch.y]
class PaintApp(App):
def build(self):
parent = Widget()
# ペイント領域
self.painter = PaintWidget()
parent.add_widget(self.painter)
# クリアボタン
clearbtn = Button(text='クリア', size_hint=(None, None), size=(100, 50))
clearbtn.bind(on_release=self.clear_canvas)
parent.add_widget(clearbtn)
return parent
def clear_canvas(self, obj):
self.painter.canvas.clear()
if __name__ == '__main__':
PaintApp().run()
KV言語を使用したレイアウト
# kv_app.py
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
# KV言語でレイアウトを定義
Builder.load_string('''
<RootWidget>:
orientation: 'vertical'
padding: 20
spacing: 10
Label:
text: 'Kivyアプリケーション'
size_hint_y: None
height: 50
font_size: 24
BoxLayout:
orientation: 'horizontal'
spacing: 10
Button:
text: 'ボタン 1'
on_press: root.button_pressed(self.text)
Button:
text: 'ボタン 2'
on_press: root.button_pressed(self.text)
Button:
text: 'ボタン 3'
on_press: root.button_pressed(self.text)
TextInput:
id: text_input
text: 'ここにテキストを入力'
multiline: False
size_hint_y: None
height: 30
Label:
id: result_label
text: '結果がここに表示されます'
text_size: self.size
halign: 'center'
valign: 'middle'
''')
class RootWidget(BoxLayout):
def button_pressed(self, button_text):
# IDを使ってウィジェットにアクセス
self.ids.result_label.text = f'{button_text} が押されました'
input_text = self.ids.text_input.text
print(f'ボタン: {button_text}, 入力: {input_text}')
class KVApp(App):
def build(self):
return RootWidget()
if __name__ == '__main__':
KVApp().run()
アニメーションとプロパティ
# animation_app.py
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.animation import Animation
from kivy.graphics import Color, Rectangle
class AnimationWidget(Widget):
def __init__(self, **kwargs):
super(AnimationWidget, self).__init__(**kwargs)
# 背景を描画
with self.canvas:
Color(0.2, 0.6, 0.8) # 青い背景
self.rect = Rectangle(size=(100, 100), pos=(50, 50))
# アニメーション用ボタン
btn = Button(text='アニメーション開始', size_hint=(None, None),
size=(200, 50), pos=(10, 10))
btn.bind(on_press=self.start_animation)
self.add_widget(btn)
def start_animation(self, instance):
# 四角形のアニメーション
anim = Animation(pos=(300, 200), size=(150, 150), duration=2)
anim += Animation(pos=(50, 50), size=(100, 100), duration=2)
anim.repeat = True
anim.bind(on_progress=self.update_rect)
anim.start(self)
def update_rect(self, animation, widget, progress):
# アニメーション中に四角形を更新
self.rect.pos = (50 + progress * 250, 50 + progress * 150)
self.rect.size = (100 + progress * 50, 100 + progress * 50)
class AnimationApp(App):
def build(self):
return AnimationWidget()
if __name__ == '__main__':
AnimationApp().run()
モバイル向けパッケージング(Buildozer設定)
# buildozer.spec
[app]
title = My Kivy App
package.name = mykivyapp
package.domain = org.example
source.dir = .
source.include_exts = py,png,jpg,kv,atlas
version = 0.1
requirements = python3,kivy
[buildozer]
log_level = 2
[app:android]
arch = arm64-v8a,armeabi-v7a
[app:android.gradle_dependencies]
implementation 'com.google.android.material:material:1.0.0'
[app:android.permissions]
android.permission.INTERNET
android.permission.WRITE_EXTERNAL_STORAGE
プロジェクト設定と実行
# 仮想環境作成(推奨)
python -m venv kivy_env
source kivy_env/bin/activate # Linux/macOS
# または
kivy_env\Scripts\activate # Windows
# Kivyインストール
python -m pip install "kivy[base]" kivy_examples
# アプリケーション実行
python hello_world.py
# Android向けビルド(Buildozer使用)
pip install buildozer
buildozer android debug
# デスクトップ向け実行ファイル作成(PyInstaller使用)
pip install pyinstaller
pyinstaller --onefile --windowed hello_world.py
# Kivyサンプル実行
python -m kivy.examples.demo.showcase
プロジェクト構造例
my_kivy_app/
├── main.py # メインアプリケーション
├── screens/
│ ├── __init__.py
│ ├── home_screen.py # ホーム画面
│ └── settings_screen.py # 設定画面
├── widgets/
│ ├── __init__.py
│ └── custom_button.py # カスタムウィジェット
├── layouts/
│ ├── home.kv # ホーム画面レイアウト
│ └── settings.kv # 設定画面レイアウト
├── assets/
│ ├── images/
│ └── sounds/
├── buildozer.spec # Android/iOSビルド設定
├── requirements.txt
└── README.md