Pythonでちょっとしたデスクトップアプリを作りたいとき、まず試してほしいのがTkinterです。
インストール不要でPythonだけあれば動くため、初心者でもすぐにGUIの基本を学べます。
本記事では、最短コードから基本ウィジェット、イベント処理、レイアウトまで順を追って丁寧に解説します。
なお、PyQtやKivyなど高機能・マルチプラットフォーム向けの選択肢は別記事で扱います。
Tkinterとは(インストール不要の標準GUI)

Tkinterの特徴(標準ライブラリ)
TkinterはPythonに標準で同梱されているGUIツールキットです。
追加インストールが不要で、Windows、macOS、Linuxの主要OSでそのまま動作します。
内部的にはTcl/Tkという成熟したGUIライブラリに橋渡しする仕組みを持ち、短いコードでシンプルなウィンドウやボタン、テキスト入力といったUI部品を作成できます。
初心者にとっての利点は以下の通りです。
あえて箇条書きにせず説明すると、まず導入が簡単で、Pythonさえあればすぐに試せる点が大きな魅力です。
コードは読みやすく、学習コストが低いため、イベント駆動の考え方やレイアウトの基本を身につけるには最適です。
さらに、サンプルや情報が豊富で、困ったときに調べやすいという安心感もあります。
どうしてインストール不要なのか
TkinterはCPython
(一般的なPython実装)に含まれて配布されるため、追加のpip install
は不要です。
ただし、一部のLinuxディストリビューションでは「tk」部分が別パッケージになっていることがあるため、その場合は後述の対処を行います。
最初に知っておきたい用語
- ウィジェット: ラベルやボタン、入力欄などのUI部品を指します。
- レイアウト: ウィジェットをウィンドウ内に配置する方法で、Tkinterでは
pack
やgrid
をよく使います。 - メインループ:
root.mainloop()
でアプリがイベント(クリックなど)を受け付け続ける仕組みです。
何が作れるか(簡単なデスクトップアプリ)
Tkinterは日常の作業を楽にする小さなツールを手早く作るのに向いています。
例えば、ファイル名の一括変更ツール、簡単な電卓、CSVの内容を確認して整形するユーティリティ、テキストテンプレートから資料の土台を作成する補助ツールなどが現実的です。
グラフ描画やフォーム入力、ダイアログを組み合わせて、必要最低限のGUIを持つアプリを構築できます。
必要環境(Pythonのみ)
前提はPython 3系のみです。
バージョンは3.8以上を目安にするとよいでしょう。
以下で確認できます。
python --version
# または
python3 --version
WindowsとmacOSでは公式サイトのインストーラで入れたPythonにTkinterが同梱されます。
Linuxでは後述の「つまずき対処」をご確認ください。
最小のTkinterアプリを作る
Hello Windowを表示(最短コード)
最短でウィンドウを表示する例です。
コメントを添えて解説します。
# hello_tk.py
# 最小限のTkinterウィンドウを表示するサンプル
import tkinter as tk # Tkinterをtkという短い名前で読み込む
root = tk.Tk() # アプリの「土台」(ルートウィンドウ)を作成
root.title("Hello Window") # ウィンドウのタイトル
root.geometry("300x120") # (任意) ウィンドウの初期サイズを指定
# ラベル(文字表示ウィジェット)を1つ配置してみる
message = tk.Label(root, text="Hello, Tkinter!")
message.pack(pady=20) # packで上下方向に配置。少し余白を入れる
root.mainloop() # イベントループを開始(これ以降、ウィンドウが表示され操作可能になる)
このコードは5行ほどでウィンドウを作れることを示しています。

Label
をpack
で配置し、mainloop()
を呼ぶだけで動作します。
つまずき対処(importできない)
ModuleNotFoundError: No module named ‘tkinter’と出た場合の対処です。
pipでtkinterはインストールできません(標準同梱のため)。
OS別の対処を紹介します。
Windows
公式インストーラでPythonを入れ直し、セットアップ時に「tcl/tk と IDLE」のコンポーネントが有効になっていることを確認します。既存インストールを「修復」してもOKです。
macOS
AppleプリインストールのPythonは古い場合があります。python.orgの公式インストーラで最新のPythonを入れるのが確実です。
Homebrewを使う場合はbrew install python
に加えてbrew install tcl-tk
が必要なことがありますが、設定が難しいため初心者は公式インストーラがおすすめです。
Linux
sudo apt-get update
sudo apt-get install -y python3-tk
sudo dnf install -y python3-tkinter
sudo pacman -S tk
基本ウィジェットとイベント(GUI)
TkinterのLabel/Button/Entry
最もよく使う3つのウィジェットを1画面に配置してみます。
ラベルの表示、テキスト入力、ボタンの押下という典型的な構成です。
# basic_widgets.py
# Label, Entry, Buttonの基本とレイアウト(pack)の例
import tkinter as tk
root = tk.Tk()
root.title("基本ウィジェット")
root.geometry("360x160")
# ラベル(表示用)
label = tk.Label(root, text="お名前を入力してください:")
label.pack(pady=(15, 5))
# テキスト入力(Entry)
name_entry = tk.Entry(root, width=30) # 幅は適宜調整
name_entry.pack(pady=5)
# ボタン(押すと何かが起きる)
def on_greet():
# Entryから文字列を取得し、挨拶メッセージを表示
name = name_entry.get() or "名無しさん"
result_label.config(text=f"こんにちは、{name} さん!")
print(f"[DEBUG] 入力値: {name}") # コンソールにデバッグ出力
greet_button = tk.Button(root, text="あいさつする", command=on_greet)
greet_button.pack(pady=5)
# 結果を表示するラベル
result_label = tk.Label(root, text="(ここに結果が表示されます)")
result_label.pack(pady=(10, 15))
root.mainloop()
実行結果
[DEBUG] 入力値: 山田

Entry.get()
で入力値を取得し、Label.config(text=...)
で表示を更新しています。
ボタンはcommand
引数に関数を渡すことでクリック時の処理を紐づけます。
ボタンクリックのイベント処理
イベント処理は関数(またはメソッド)とウィジェットの関連付けで実現します。
ボタン以外にも、キー入力やマウス操作などをbind
で扱えます。
サンプルコード(クリックとキー入力)
# events.py
# Buttonのcommandと、Enterキーのbindを併用する例
import tkinter as tk
root = tk.Tk()
root.title("イベント処理")
entry = tk.Entry(root)
entry.pack(padx=12, pady=12)
def submit():
text = entry.get()
print(f"[INFO] 送信: {text}")
entry.delete(0, tk.END)
submit_btn = tk.Button(root, text="送信", command=submit)
submit_btn.pack(pady=6)
# Enterキーで送信する(Entryにフォーカスがある時に発火)
entry.bind("<Return>", lambda e: submit())
root.mainloop()
実行結果(コンソール出力の例)
[INFO] 送信: こんにちは
command=関数
はボタン専用の「簡単」なやり方、bind
はより汎用的なイベントフックです。
フォームではボタンとEnterキーを併用すると使いやすくなります。
メッセージを更新する
メッセージの更新にはLabel.config
の他にStringVar
の利用が便利です。
データと表示のひも付けができ、値を変更すると自動でラベルにも反映されます。
サンプルコード(StringVarで双方向っぽく)
# update_message.py
# StringVarを使ってLabelの表示を簡潔に更新する
import tkinter as tk
root = tk.Tk()
root.title("メッセージ更新")
message_var = tk.StringVar(value="初期メッセージ")
label = tk.Label(root, textvariable=message_var)
label.pack(pady=10)
entry = tk.Entry(root)
entry.pack(pady=5)
def apply_text():
message_var.set(entry.get() or "(空)")
print(f"[TRACE] 新メッセージ: {message_var.get()}")
apply_btn = tk.Button(root, text="適用", command=apply_text)
apply_btn.pack(pady=10)
root.mainloop()
実行結果(コンソール出力の例)
[TRACE] 新メッセージ: 変更しました
textvariable
にStringVar
を渡し、set()
で値を更新すると表示に反映されます。
状態管理が見通しやすくなるので、複数のウィジェットで同じ値を共有したい場合にも有用です。
ファイルダイアログ(filedialog)を使う
ファイルを選ぶUIは標準のダイアログを使うのが最も簡単です。
tkinter.filedialog
のaskopenfilename
などを利用します。
サンプルコード(ファイル選択)
# open_file_dialog.py
# ファイルを選択してパスを表示する
import tkinter as tk
from tkinter import filedialog as fd # 別名fdで使うのが一般的
root = tk.Tk()
root.title("ファイルを開く")
path_var = tk.StringVar(value="(未選択)")
def choose_file():
# 複数フィルタを設定(任意)
filetypes = [
("テキスト", "*.txt"),
("CSV", "*.csv"),
("すべてのファイル", "*.*"),
]
filename = fd.askopenfilename(
title="ファイルを選択",
filetypes=filetypes
)
if filename:
path_var.set(filename)
print(f"[FILE] 選択: {filename}")
else:
print("[FILE] キャンセルされました")
tk.Button(root, text="ファイルを選択", command=choose_file).pack(pady=12)
tk.Label(root, textvariable=path_var, wraplength=380, justify="left").pack(padx=12, pady=(0, 12))
root.mainloop()
実行結果(コンソール出力の例)
[FILE] 選択: /Users/user/Documents/sample.txt
filetypes
で拡張子フィルタを指定できます。
結果は空文字列の可能性があるため、if filename:
でキャンセル判定を行いましょう。
レイアウトの基礎
レイアウトはpack
とgrid
が中心です。
同じ親ウィジェット内でpackとgridを混在させないのが最大の注意点です。
使い分けを理解すると、配置の悩みが大きく減ります。
packの使い方
pack
は「上下左右に積む」イメージで、シンプルな画面に向いています。
side
、fill
、expand
、padx/pady
を押さえましょう。
# layout_pack.py
# packで上下に積み、ボタンを左右に並べる例(Frameを活用)
import tkinter as tk
root = tk.Tk()
root.title("packの例")
root.geometry("360x180")
title_label = tk.Label(root, text="packレイアウト", font=("Meiryo", 12, "bold"))
title_label.pack(pady=10)
# 下段のボタンを左右に並べるためにFrameを用意
button_row = tk.Frame(root, bd=1, relief="groove")
button_row.pack(fill="x", padx=10, pady=10)
tk.Button(button_row, text="左", width=10).pack(side="left", padx=10, pady=10)
tk.Button(button_row, text="中央", width=10).pack(side="left", padx=10, pady=10)
tk.Button(button_row, text="右", width=10).pack(side="left", padx=10, pady=10)
# 余白を確保したフッタ
footer = tk.Label(root, text="フッタ", fg="#666")
footer.pack(side="bottom", pady=8)
root.mainloop()

横並びにしたいときはFrame
を作って、その中でside="left"
を使うと直感的です。
画面を論理的なブロックに分けることで可読性も上がります。
gridの使い方
grid
は「表形式」に配置するやり方で、フォーム画面に最適です。
row
、column
、sticky
、columnconfigure
などを覚えると自在に調整できます。
# layout_grid.py
# gridでラベルと入力欄を2列に揃えるフォームの例
import tkinter as tk
root = tk.Tk()
root.title("gridの例")
root.geometry("420x200")
# 列の伸縮設定(1列目=入力欄を伸縮させる)
root.columnconfigure(1, weight=1)
# 1行目
tk.Label(root, text="氏名").grid(row=0, column=0, padx=8, pady=8, sticky="e")
name_entry = tk.Entry(root)
name_entry.grid(row=0, column=1, padx=8, pady=8, sticky="we")
# 2行目
tk.Label(root, text="メール").grid(row=1, column=0, padx=8, pady=8, sticky="e")
mail_entry = tk.Entry(root)
mail_entry.grid(row=1, column=1, padx=8, pady=8, sticky="we")
# 3行目(ボタンを右寄せ)
submit_btn = tk.Button(root, text="送信")
submit_btn.grid(row=2, column=1, padx=8, pady=12, sticky="e")
root.mainloop()

sticky="we"
は左右に伸ばす指定、columnconfigure(1, weight=1)
で2列目がウィンドウ幅に合わせて広がるように設定しています。
フォームUIはgridで作ると整えやすいです。
packとgridを混ぜないコツ
同じ親ウィジェット(同じFrameや同じroot)内でpackとgridを混在させるとエラーやレイアウト崩れの原因になります。
混ぜたい場合はFrameで親を分けるのが鉄則です。
サンプルコード(正しい混在方法)
# mix_pack_grid.py
# packとgridを併用したい場合は、親Frameを分ける
import tkinter as tk
root = tk.Tk()
root.title("packとgridの併用")
# 上部はpackで縦積み
top = tk.Frame(root, bd=1, relief="ridge")
top.pack(fill="x", padx=10, pady=10)
tk.Label(top, text="上部はpack").pack(pady=5)
tk.Button(top, text="ボタンA").pack(pady=5)
# 下部はgridでフォーム
bottom = tk.Frame(root, bd=1, relief="ridge")
bottom.pack(fill="both", expand=True, padx=10, pady=10)
bottom.columnconfigure(1, weight=1)
tk.Label(bottom, text="ID").grid(row=0, column=0, padx=8, pady=8, sticky="e")
tk.Entry(bottom).grid(row=0, column=1, padx=8, pady=8, sticky="we")
tk.Label(bottom, text="パスワード").grid(row=1, column=0, padx=8, pady=8, sticky="e")
tk.Entry(bottom, show="*").grid(row=1, column=1, padx=8, pady=8, sticky="we")
tk.Button(bottom, text="ログイン").grid(row=2, column=1, padx=8, pady=10, sticky="e")
root.mainloop()

packとgridの使い分け(比較表)
項目 | pack | grid |
---|---|---|
概念 | 上下左右に積む | 表の行と列で置く |
得意分野 | 単純な縦積み/横並び | 入力フォーム、複雑な整列 |
主なオプション | side, fill, expand, padx/pady | row/column, sticky, columnconfigure |
注意点 | 細かな整列が苦手 | 初期学習コストがやや高い |
コツ
- シンプルに並べたい場合は
pack
、整列が重要なフォームはgrid
。 - 混在するときはFrameで領域を分けるのを習慣化しましょう。
まとめ
本記事では、インストール不要で今すぐ始められるTkinterを使い、最小のウィンドウ表示からウィジェット、イベント処理、ファイルダイアログ、そしてレイアウトの基礎までを一気に学びました。
要点は、短いコードで試す→動く実感を得る→少しずつ機能を足すという流れです。
packとgridの使い分け、StringVar
による表示更新、そしてOS別の「importできない」対処を押さえれば、日常作業を助ける小さなツールはすぐに作れます。
まずはサンプルを写経し、必要に応じてボタンやエントリを追加して、あなたの用途に合ったデスクトップアプリに育てていきましょう。