スマホでも動くPythonアプリを最短で形にしたいなら、Kivyはとても有力な選択肢です。
ひとつのコードベースでAndroidとiOSに対応でき、見た目やレイアウトは専用のkv言語で簡潔に書けます。
本記事では、Python初心者でもKivyで動くアプリをPC上で試し、最終的にスマホへ配布できるところまで丁寧に解説します。
Kivyとは何か



Kivyの特徴(Android/iOS対応のクロスプラットフォーム)
1つのコードで複数OSに対応
KivyはPython
で書いたアプリをデスクトップ(Windows/macOS/Linux)、Android、iOSに展開できるオープンソースフレームワークです。
描画はOpenGLベースで高速に動作し、タッチ操作やジェスチャ、スクロールなどスマホ向けのUI要素も標準で備えています。
kv言語でUIを宣言的に記述
Kivyにはkv言語
というテンプレートがあり、Pythonコードと見た目(レイアウトやスタイル)を分離できます。
見た目の変更はkv、ロジックはPythonと役割を分けられるため、学習しやすく保守もしやすくなります。
無償・オープンソース
KivyはMITライセンスで無償利用できます。
商用アプリも配布可能です。
できること・向いているアプリ(初心者向け)
得意分野とユースケース
Kivyは以下のようなアプリに向いています。
複雑な3Dゲームよりはツール系や教育用、業務補助のユーティリティと相性が良いです。
- 入力フォームやチェックリスト、メモ、タイマーなどの小型ツール
- データビューア(画像/テキスト/簡単なグラフ表示)
- 教育/学習アプリ、プロトタイピング
- センサー/カメラを使うシンプルなネイティブアプリ
実運用の大型アプリや最新のOS固有UIを強く求める場合は工夫が必要ですが、まずは「動くもの」を短時間で作る点では非常に優秀です。
学習の前提(基本のPythonだけでOK)
必要な知識
Pythonの基本文法(関数、クラス、モジュール、import)が分かれば十分です。
非同期処理や並列処理は後から段階的に学べます。
フロントエンドやネイティブ開発の事前知識は不要です。
iOS向けビルドはmacOSとXcode、Apple Developer Program(有料)が必要です。
Android向けビルドはLinuxまたはWSL2(Windows上)が実用的です。
開発環境の準備(インストールと動作確認)
Pythonの用意(推奨バージョン)
どのバージョンを入れるべきか
Kivy 2.2以降はPython 3.10〜3.12での利用実績がありますが、ビルドツール群(特にAndroid)の安定性を考えるとPython 3.10または3.11を推奨します。
Windows/Macは公式インストーラ、Linuxはディストリビューションまたはpyenvを利用してください。
以下は目安です。
OS | 推奨Python | 備考 |
---|---|---|
Windows 10/11 | 3.10/3.11 | WSL2でAndroidビルドを行うのが安定 |
macOS 12以降(Apple Silicon可) | 3.10/3.11 | iOSビルドはXcode必須 |
Ubuntu 22.04/24.04 | 3.10/3.11 | Androidビルドが最も楽 |
Python 3.12でもPC上の実行は概ね動きますが、Androidパッケージングでは依存関係の相性に注意してください。
venvで仮想環境を作成
OS別コマンド
プロジェクトごとに仮想環境を作ると依存関係が衝突しません。
Windows(PowerShell)
# 任意の作業フォルダへ
PS> mkdir kivy-hello; cd kivy-hello
# 仮想環境の作成
PS> py -3.11 -m venv .venv
# 有効化
PS> .\.venv\Scripts\Activate.ps1
# pipを更新
(.venv) PS> python -m pip install -U pip setuptools wheel
macOS/Linux(Bash)
# 任意の作業フォルダへ
$ mkdir kivy-hello && cd kivy-hello
# 仮想環境の作成
$ python3 -m venv .venv
# 有効化
$ source .venv/bin/activate
# pipを更新
(.venv) $ python -m pip install -U pip setuptools wheel
Kivyのインストール(pip)
最小構成の導入
(.venv) $ pip install "kivy[base]" # まずは最小
# 例: 音声や各種機能まで含めたい場合は
# (.venv) $ pip install "kivy[full]"
こちらのコマンドを使えばWindowsでビルド済みwheelが落ちてくるため、追加のビルドツールなしで入ることが多いです。
失敗した場合はVisual C++再頒布可能パッケージを入れて再試行してください。
エディタ設定(VS Code推奨)
本格的な開発であれば必須級ですが、入れなくても開発可能です。
拡張機能と設定
- Python拡張機能(Microsoft)とPylanceを導入します。
- Kivy Language拡張(ある場合)を入れると
.kv
のシンタックスハイライトが効きます。 - VS CodeでPythonインタプリタに
.venv
を選択し、実行/デバッグ構成を作ると便利です。
サンプル起動で確認(Hello World)
最小サンプル
まずは1つのボタンがあるだけのアプリを起動してみます。
クリック(タップ)でコンソールへメッセージを出します。
# main.py
# Kivyの最小例: ボタンを押すとコンソールに"Hello, Kivy!"を表示します。
from kivy.app import App
from kivy.uix.button import Button
class HelloApp(App):
def build(self):
# Buttonウィジェットをそのままルートとして返す
btn = Button(text="Hello Kivy")
# on_pressイベントにPython関数をバインド
btn.bind(on_press=self.say_hello)
return btn
def say_hello(self, instance):
print("Hello, Kivy!") # コンソール出力
if __name__ == "__main__":
HelloApp().run()
実行はいつもどおりの実行コマンドで大丈夫です。
(.venv) $ python main.py

Hello, Kivy!
Hello, Kivy!
# ボタンを押すたびに行が増えます
ウィンドウ(またはスマホでは画面)が立ち上がり、ボタンのタップに反応すれば成功です。
最初のKivyアプリ(基本UIとkv言語)
アプリの骨組み(AppとWidget)
Appクラスとルートウィジェット
KivyアプリはApp
クラスを継承して作り、build()
で返したウィジェットがルートになります。
複数のウィジェットを並べたい場合はレイアウトを使います。
# main.py
# AppとカスタムWidgetを定義し、構造を分かりやすくします。
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
class MainView(BoxLayout):
pass # レイアウトと見た目はkvに任せる
# structure.kvが自動で読み込まれます。
class StructureApp(App):
def build(self):
return MainView()
if __name__ == "__main__":
StructureApp().run()
#:kivy 2.1.0
# ファイル名はAppクラス名(StructureApp)から"App"を除いた小文字= structure.kv が自動で読み込まれます。
<MainView>:
orientation: "vertical"
padding: "12dp"
spacing: "8dp"
Label:
text: "Kivy構造の基本"
font_size: "20sp"
Button:
text: "押してみる"
on_press: app.root.ids.status.text = "押されました!" # kvからウィジェット更新
Label:
id: status
text: "待機中..."

ちなみに、デフォルトのフォントは日本語非対応であるため、日本語を扱う場合は日本語に対応しているフォントファイル(.ttf
または.otf
)が必要です。
import os
from kivy.resources import resource_add_path
from kivy.core.text import LabelBase, DEFAULT_FONT
# fontsフォルダのパスを追加
resource_add_path(os.path.join(os.path.dirname(__file__), 'fonts'))
# デフォルトフォントをIPAexゴシックに設定
LabelBase.register(DEFAULT_FONT, 'ipaexg.ttf')
日本語フォントの表示を試してみたい場合は、以下のIPAexフォントで試してみてください。
IPAが提供する無料の日本語ゴシック体フォント。JIS X 0213:2004準拠で文字数が多く、可読性の高さからWebや印刷物、各種ソフトウェアで広く利用される。
レイアウト(BoxLayout/GridLayoutの基礎)
横並び/縦並びとグリッド
BoxLayoutは横(horizontal
)や縦(vertical
)に子要素を並べる最も基本的なレイアウトです。
GridLayoutは行列で整列します。
#:kivy 2.1.0
BoxLayout:
orientation: "horizontal" # 左から右へ並ぶ
spacing: "6dp"
Button:
text: "左"
Button:
text: "中央"
Button:
text: "右"
上記layoutsample.kv
を読み込むなら、LayoutSampleApp
クラスを作成して実行します。
from kivy.app import App
class LayoutSampleApp(App):
pass
if __name__ == "__main__":
LayoutSampleApp().run()

グリッドレイアウトにしたい場合は、以下のようにGridLayout
を使用します。
#:kivy 2.1.0
GridLayout:
cols: 2 # 2列のグリッド
row_default_height: "40dp"
row_force_default: True
spacing: "4dp"
Button:
text: "1"
Button:
text: "2"
Button:
text: "3"
Button:
text: "4"

ウィジェット(Button/Label/TextInput)
よく使う基本ウィジェット
- Label: 文字を表示
- Button: 押してイベントを発火
- TextInput: 文字入力
#:kivy 2.1.0
BoxLayout:
orientation: "vertical"
padding: "12dp"
spacing: "8dp"
Label:
text: "お名前を入力してください"
TextInput:
id: name_field
hint_text: "たろう"
multiline: False
Button:
text: "送信"
on_press: print("name:", name_field.text) # コンソールへ出力
name: たろう

イベント処理(on_pressなどのバインド)
Python側へイベントを渡す
イベントはbind()
でPython関数に紐付けられます。
引数instance
にはイベント元ウィジェットが入ります。
# events.py
# on_pressやテキスト変更イベントを受け取る例
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty
class EventView(BoxLayout):
message = StringProperty("")
def submit(self):
# kvから呼ばれるメソッド
print(f"submitted: {self.ids.name_field.text}")
self.message = f"こんにちは、{self.ids.name_field.text}"
class EventApp(App):
def build(self):
return EventView()
if __name__ == "__main__":
EventApp().run()
#:kivy 2.1.0
<EventView>:
orientation: "vertical"
padding: "12dp"
spacing: "8dp"
TextInput:
id: name_field
hint_text: "あなたの名前"
multiline: False
on_text: print("typing:", self.text) # 入力中にコンソールへ
Button:
text: "送信"
on_press: root.submit() # Pythonメソッドを呼ぶ
Label:
text: root.message
typing: た
typing: たろ
typing: たろう
submitted: たろう
kv言語の基本(見た目の分離)
規約とバインド
MyApp
というクラス名のアプリはmy.kv
を自動読み込みします(「App」を除いて小文字)。<ClassName>:
のルールでウィジェットの見た目を宣言できます。id
で参照し、Python側ではself.ids.id名
でアクセスします。
# kv_basic.py
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
class KvRoot(BoxLayout):
pass
class KvBasicApp(App):
def build(self):
return KvRoot()
if __name__ == "__main__":
KvBasicApp().run()
#:kivy 2.1.0
# kvbasic.kv (KvBasicApp -> kvbasic.kv)
<KvRoot>:
orientation: "vertical"
padding: "12dp"
spacing: "8dp"
Label:
id: title
text: "kv言語の基本"
font_size: "22sp"
Button:
text: "タイトル変更"
on_press: title.text = "変更されました"

画面遷移(ScreenManagerの入門)
2画面を往復してみる
ScreenManager
を使うと複数画面の切り替えが簡単です。
# screens.py
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen, SlideTransition
class HomeScreen(Screen):
pass
class DetailScreen(Screen):
pass
class ScreenApp(App):
def build(self):
sm = ScreenManager(transition=SlideTransition())
sm.add_widget(HomeScreen(name="home"))
sm.add_widget(DetailScreen(name="detail"))
return sm
if __name__ == "__main__":
ScreenApp().run()
#:kivy 2.1.0
# screenapp.kv
<HomeScreen>:
BoxLayout:
orientation: "vertical"
padding: "12dp"
spacing: "8dp"
Label:
text: "ホーム"
Button:
text: "詳細へ"
on_press: app.root.current = "detail"
<DetailScreen>:
BoxLayout:
orientation: "vertical"
padding: "12dp"
spacing: "8dp"
Label:
text: "詳細画面"
Button:
text: "戻る"
on_press: app.root.current = "home"
画像とアイコンの表示(サイズと比率)
Imageウィジェットの基本
画像はImage
で表示できます。
比率保持や伸縮の制御が重要です。
#:kivy 2.1.0
# image_sample.kv
BoxLayout:
orientation: "vertical"
padding: "12dp"
spacing: "8dp"
Image:
source: "assets/photo.png" # 画像ファイルの相対パス
allow_stretch: True # 親に合わせて伸縮を許可
keep_ratio: True # 縦横比は維持
size_hint_y: 0.7 # 画面の7割を画像に
Label:
text: "画像は比率を維持して表示されます"
アイコンはビルド時にアプリ全体のアイコンとして指定します(後述のbuildozer.spec)。
タッチ操作とスクロールの扱い
on_touch_*の基本
独自のタッチ処理はon_touch_down/on_touch_move/on_touch_up
をオーバーライドします。
スクロールにはScrollView
を使います。
# touch_scroll.py
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.graphics import Color, Rectangle # 必要なモジュールをインポート
class TouchArea(FloatLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
# 背景色を描画するためのcanvas設定を追加
with self.canvas.before:
# 色を薄いグレーに設定 (R, G, B, A)
Color(0.85, 0.85, 0.85, 1)
# ウィジェットのサイズと位置に追従する四角形を描画
self.rect = Rectangle(size=self.size, pos=self.pos)
# ウィジェットのサイズや位置が変わったときに背景の四角形も更新する
self.bind(pos=self.update_rect, size=self.update_rect)
def update_rect(self, instance, value):
"""Rectangleのposとsizeを更新するコールバック関数"""
self.rect.pos = instance.pos
self.rect.size = instance.size
def on_touch_down(self, touch):
# 自分の領域内だけ処理する
if self.collide_point(*touch.pos):
print(f"down: {touch.pos}")
return True
return super().on_touch_down(touch)
def on_touch_move(self, touch):
if self.collide_point(*touch.pos):
print(f"move: {touch.pos}")
return True
return super().on_touch_move(touch)
def on_touch_up(self, touch):
if self.collide_point(*touch.pos):
print(f"up: {touch.pos}")
return True
return super().on_touch_up(touch)
class TouchScrollApp(App):
def build(self):
root = BoxLayout(orientation="vertical", spacing=8, padding=12)
root.add_widget(TouchArea(size_hint_y=0.4))
# 縦スクロール
scroll = ScrollView(size_hint_y=0.6)
content = BoxLayout(orientation="vertical", size_hint_y=None, spacing=6)
content.bind(minimum_height=content.setter("height"))
for i in range(30):
content.add_widget(Label(text=f"Item {i}", size_hint_y=None, height=32))
scroll.add_widget(content)
root.add_widget(scroll)
return root
if __name__ == "__main__":
TouchScrollApp().run()
down: (123.0, 250.0)
move: (130.5, 245.0)
up: (130.5, 245.0)
スマホで動かす(Android/iOSのビルド)
Android向け(Buildozerの準備)
Buildozerとは
Buildozer
はKivyアプリをAndroid向けにビルドする自動化ツールです。
内部でpython-for-android(p4a)
を使い、依存ライブラリもまとめてAPK/AABにします。
LinuxまたはWSL2(Windows)での実行が安定です。
必要パッケージの例(Ubuntu/WSL2)
# 基本ツール
$ sudo apt update
$ sudo apt install -y python3-venv python3-pip git build-essential \
openjdk-17-jdk unzip zip libffi-dev libssl-dev
# プロジェクト仮想環境で
$ python3 -m venv .venv && source .venv/bin/activate
(.venv) $ pip install -U pip setuptools wheel cython
(.venv) $ pip install buildozer
Windowsネイティブ上のUSBデバイスはWSLから直接扱いにくいため、APKのインストールはadb(Windows側)で行うか、buildozer android debug
で生成したファイルを手動転送します。
APK作成と実機インストール
buildozer.specの生成と編集
(.venv) $ buildozer init # buildozer.spec を生成
# 依存ライブラリは requirements にカンマ区切り: kivy, requests など
# パッケージ名やアイコンもspecで設定(後述)
主な編集箇所(抜粋):
# buildozer.spec 抜粋
[app]
title = My Kivy App
package.name = mykivyapp
package.domain = org.example
source.dir = .
version = 0.1.0
# Play向けはAAB推奨
android.release_artifact = aab
# Pythonで使う依存ライブラリ
requirements = python3,kivy,requests
# 自前のアプリアイコン
icon.filename = assets/icon.png
[buildozer]
log_level = 2
デバッグビルドとインストール
# デバッグAPK/AABの作成
(.venv) $ buildozer -v android debug
# 端末をUSBデバッグ接続し、インストールと起動
(.venv) $ buildozer android deploy run
生成物の場所:
bin/ # APKやAABが出力されます
adbで直接入れる場合:
$ adb install -r bin/mykivyapp-0.1.0-debug.apk
iOS向け(Kivy-iOSとXcodeの流れ)
前提と概略
iOSはmacOSとXcodeが必須です。
配布にはApple Developer Program(有料)が必要です。
Kivy-iOSツールチェーンで依存をビルドし、Xcodeプロジェクトとして開きます。
セットアップの例
# XcodeとCommand Line ToolsをApp Storeなどから導入
# Homebrewでビルドツール
$ brew install autoconf automake libtool pkg-config
$ python3 -m venv .venv && source .venv/bin/activate
(.venv) $ pip install kivy "cython<3.1" # 依存相性に応じてピン止め
(.venv) $ pip install kivy-ios
# Kivy-iOSで依存のビルド(時間がかかります)
(.venv) $ toolchain build python3 kivy sdl2 openssl
# プロジェクトの作成(例: 本体は../myapp ディレクトリ)
(.venv) $ toolchain create ios mykivyapp ../myapp
# 生成されたXcodeプロジェクトを開く
(.venv) $ open mykivyapp-ios/mykivyapp.xcodeproj
Xcodeでターゲットを実機またはシミュレータに合わせ、署名設定(チーム/Bundle ID)を済ませてビルドします。
パーミッション設定(AndroidManifest/iOS Info)
Androidの権限
buildozer.spec
のandroid.permissions
に権限を列挙します。
# buildozer.spec 抜粋
[app]
android.permissions = INTERNET, CAMERA, WRITE_EXTERNAL_STORAGE
# ネットワークやカメラを使う場合は適切な権限を追加
iOSのInfo.plistキー
カメラや写真ライブラリ等を使う場合、利用理由を明記する必要があります。
# buildozer.spec 抜粋
[app]
ios.plist_keys = NSCameraUsageDescription=カメラをQRコード読み取りに使用します, \
NSPhotoLibraryAddUsageDescription=画像保存のために使用します
画面サイズ対応(解像度とDP)
dp/spを使ってスケーリング
Kivyはkivy.metrics
のdp
とsp
で密度非依存の長さを扱えます。
UI寸法は数値ではなくdp/sp文字列または関数で指定すると、端末解像度が変わっても破綻しにくくなります。
# metrics_dp.py
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.metrics import dp, sp
class MetricsApp(App):
def build(self):
root = BoxLayout(orientation="vertical", padding=dp(12), spacing=dp(8))
from kivy.uix.label import Label
from kivy.uix.button import Button
root.add_widget(Label(text="dp/spの例", font_size=sp(20)))
root.add_widget(Button(text="押す", size_hint_y=None, height=dp(44)))
return root
if __name__ == "__main__":
MetricsApp().run()
kvでも文字列で指定できます(例: "12dp"
, "20sp"
)。
パッケージ名/アイコン/バージョン設定
よく使うspec項目
# buildozer.spec 抜粋
[app]
title = Sample App
package.name = sampleapp
package.domain = com.example # 逆ドメイン形式
version = 1.2.3 # 人が読む版
android.numeric_version = 10203 # 内部用。1.2.3 -> 10203 のように増加必須
icon.filename = assets/icon.png # 512x512以上推奨
# AABでPlayに提出する場合
android.release_artifact = aab
# ターゲットAPI等(必要に応じて指定)
# android.api = 34
# android.minapi = 23
よくあるエラーと対処(Build失敗/依存関係)
典型的トラブル一覧
症状/メッセージ | 原因の傾向 | 対処 |
---|---|---|
Java関連のエラー(JDK not found) | JDK未導入/バージョン不整合 | OpenJDK 17を導入しPATHを確認 |
Cコンパイラが見つからない | build-essential未導入 | Ubuntuならaptでbuild-essentialを入れる |
Couldn’t find Android SDK/NDK | 初回セットアップ未完 | Buildozerが自動取得するが、プロキシや権限に注意。再実行や環境変数確認 |
failed building wheel for XXX | ネイティブ依存のpipパッケージ | 代替パッケージ検討、バージョン固定、p4aのrecipes対応を確認 |
Python 3.12でp4a依存が壊れる | 依存の未対応 | 3.10/3.11へ切り替え、requirementsを見直す |
iOSでコードサイン失敗 | 証明書/プロビジョニング未設定 | XcodeのSigning & Capabilitiesで正しいTeamとBundle IDを設定 |
Permissionが効かない | 設定漏れ | buildozer.specのpermissions/ios.plist_keysを見直し |
ビルドログは長いですが、実際に失敗したステップより少し上に原因があることが多いです。
-v
オプションで詳細ログを有効化し、該当箇所を検索してください。
リリースの流れ(Google Play/TestFlight)
Android(Google Play)
- バージョンを更新(
version
とandroid.numeric_version
を増やす)。 - AABを作成。
(.venv) $ buildozer android release # buildozer.spec に android.release_artifact = aab を設定しておく
- 署名はGoogle Play App Signingを使う場合、アップロードキーを設定します。Buildozerが生成するキーを使うか、既存の.jksを指定します。
- Play Consoleで新しいリリースを作成し、AABをアップロードします。テストトラック(内部/クローズド)で配布して確認後、プロダクションへ昇格します。
初回提出ではプライバシーポリシーやターゲットAPI要件、64bit対応などのチェックがあります。
警告が出た項目を1つずつ解決してください。
iOS(TestFlight/本番配信)
- バージョン/ビルド番号をXcode側で更新。
- Archiveを作成し、Organizerから「Distribute App」。
- App Store Connectにアップロードし、TestFlightでテスター配布。
- レビュー申請が通ればApp Storeで公開可能です。
まとめ
KivyはPythonだけでPC・Android・iOSを横断するUIアプリを構築できる実用的なフレームワークです。
kv言語で見た目をすっきり分離し、ScreenManager
やScrollView
などの標準部品を組み合わせれば、初心者でも短期間でプロトタイプから配布まで到達できます。
Android向けにはBuildozer
、iOS向けにはKivy-iOS + Xcode
を使い、permissionsやアイコン、バージョンをbuildozer.spec
で管理するのが基本です。
環境差によるビルドエラーは避けにくいですが、Python 3.10/3.11の採用や依存のピン止め、詳細ログの確認で多くは解決できます。
まずは本記事のHello Worldから始め、少しずつレイアウトやイベント、画面遷移を加えていけば、スマホで動く「自分のアプリ」に着実に近づけます。