7日目のゴール
7日目のテーマは
「ここまでの GUI 基礎とボタンイベントを“1つの完成アプリ”としてまとめる」 ことです。
これまで6日間であなたはすでに、
ウィンドウ・ラベル・ボタン・Entry・Listbox
pack / grid / Frame によるレイアウト
ボタンで状態を切り替える
ボタンでデータを追加・更新・表示する
という、GUIアプリの土台を全部通っています。
7日目では、それらを統合して、
画面切り替え
入力フォーム
一覧表示
削除(確認ダイアログ付き)
を備えた「小さなタスク管理 GUI アプリ」を完成させます。
アプリの全体像を言葉で設計する
どんな GUI アプリを作るか
作るのは、シンプルな「タスク管理アプリ」です。
タスク名を入力して追加できる
登録されたタスクを一覧で見られる
一覧からタスクを選んで削除できる
削除時には確認ダイアログを出す
画面は「入力」と「一覧」を切り替えられる
ここに、7日間で学んだ要素を全部乗せていきます。
データ構造と「真実の置き場所」
タスクはどこに保存しておくか
まずは、アプリの中でタスクをどう持つかを決めます。
ここではシンプルに、
「文字列のリスト」として持ちます。
tasks = []
Pythonこの tasks が「真実のデータ」です。
Listbox はあくまで「画面に見せるためのコピー」です。
この「本体(tasks)と表示(Listbox)を分ける」意識が、
中級者としてとても大事なポイントです。
画面構成:メニュー・入力・一覧
Frame で画面を分ける
ウィンドウの中を、ざっくり3つのエリアに分けます。
上部:画面切り替えボタン(メニュー)
中央:入力画面(Frame)
中央:一覧画面(別の Frame)
メニューは常に表示し、
中央部分だけ「入力」か「一覧」かを切り替えます。
import tkinter as tk
from tkinter import messagebox
tasks = []
def show_input_frame():
frame_list.pack_forget()
frame_input.pack(fill="both", expand=True)
def show_list_frame():
frame_input.pack_forget()
refresh_listbox()
frame_list.pack(fill="both", expand=True)
root = tk.Tk()
root.title("タスク管理アプリ")
frame_menu = tk.Frame(root)
frame_menu.pack(fill="x")
button_to_input = tk.Button(frame_menu, text="タスク入力", command=show_input_frame)
button_to_input.pack(side="left", padx=5, pady=5)
button_to_list = tk.Button(frame_menu, text="タスク一覧", command=show_list_frame)
button_to_list.pack(side="left", padx=5, pady=5)
frame_input = tk.Frame(root)
frame_list = tk.Frame(root)
Pythonここでの重要ポイントは、
入力用 Frame と一覧用 Frame を両方作っておき、
「どちらを pack するか」で画面を切り替えていることです。
入力画面:タスク追加の流れを作る
Entry とボタンでタスクを追加する
入力画面には、
タスク名のラベル
タスク名の Entry
「追加」ボタン
メッセージ表示用ラベル
を置きます。
label_task = tk.Label(frame_input, text="タスク名:")
label_task.grid(row=0, column=0, padx=5, pady=5, sticky="e")
entry_task = tk.Entry(frame_input, width=30)
entry_task.grid(row=0, column=1, padx=5, pady=5)
button_add = tk.Button(frame_input, text="追加", command=lambda: add_task())
button_add.grid(row=0, column=2, padx=5, pady=5)
label_message = tk.Label(frame_input, text="タスク名を入力して「追加」を押してください。")
label_message.grid(row=1, column=0, columnspan=3, pady=10)
Pythonここでは grid を使って、
ラベル・Entry・ボタンを横一列に並べています。
タスク追加のロジック
add_task 関数を丁寧に分解する
def add_task():
text = entry_task.get().strip()
if text == "":
label_message.config(text="タスク名が空です。入力してください。")
return
tasks.append(text)
entry_task.delete(0, tk.END)
label_message.config(text=f"タスク「{text}」を追加しました。")
Pythonこの関数の役割は、
「追加ボタンが押されたときの一連の流れ」です。
Entry から文字列を取り出す
空ならエラーメッセージを表示して終了
空でなければ tasks に追加する
入力欄を空に戻す
メッセージラベルでフィードバックする
ここでの重要ポイントは、
データを変えているのは tasks.append(text) の1行だけ
それ以外は全部「画面の状態を変える処理」
ということです。
この意識があると、
後で「保存」「読み込み」を足すときに、
どこを触ればいいかがすぐ分かります。
一覧画面:Listbox と削除ボタン
Listbox にタスク一覧を表示する
一覧画面には、
「タスク一覧」というラベル
タスクを表示する Listbox
「削除」ボタン
ステータスメッセージ用ラベル
を置きます。
label_list_title = tk.Label(frame_list, text="タスク一覧")
label_list_title.pack(pady=5)
listbox_tasks = tk.Listbox(frame_list, height=8, width=40)
listbox_tasks.pack(padx=10, pady=5)
button_delete = tk.Button(frame_list, text="選択したタスクを削除", command=lambda: delete_task())
button_delete.pack(pady=5)
label_status = tk.Label(frame_list, text="タスクを選択して「削除」を押してください。")
label_status.pack(pady=5)
PythonListbox は、
「tasks の中身をユーザーに見せる窓」
という位置づけです。
一覧の更新:refresh_listbox
データと表示を同期させる
def refresh_listbox():
listbox_tasks.delete(0, tk.END)
for task in tasks:
listbox_tasks.insert(tk.END, task)
Pythonこの関数は、
「今の tasks の内容を Listbox に反映する」
という一点だけを担当します。
show_list_frame の中でこれを呼ぶことで、
一覧画面に切り替えたタイミングで
常に最新のタスク一覧が表示される
という状態を作っています。
削除処理:選択・確認・削除・再表示
delete_task の流れを丁寧に追う
def delete_task():
selection = listbox_tasks.curselection()
if not selection:
label_status.config(text="削除するタスクを選択してください。")
return
index = selection[0]
task = tasks[index]
result = messagebox.askokcancel("確認", f"「{task}」を削除しますか?")
if not result:
label_status.config(text="削除をキャンセルしました。")
return
del tasks[index]
refresh_listbox()
label_status.config(text=f"タスク「{task}」を削除しました。")
Pythonここには、7日目のエッセンスが詰まっています。
listbox_tasks.curselection() で、
「今選ばれている行のインデックス」を取得しています。
何も選ばれていなければ、メッセージを出して終了。
選ばれていれば、そのインデックスからtasks[index] で本体のタスクを取り出します。
削除前に messagebox.askokcancel で確認ダイアログを出し、
OK が押されたときだけ削除を実行します。
削除は del tasks[index] で本体から消し、refresh_listbox() で表示を更新し、
最後にステータスメッセージを更新します。
ここでの超重要ポイントは、
削除の対象はあくまで tasks(本体)
Listbox は refresh_listbox で「後から追従する」
という構造になっていることです。
全コード(完成版)
7日目の統合 GUI アプリ
import tkinter as tk
from tkinter import messagebox
tasks = []
def add_task():
text = entry_task.get().strip()
if text == "":
label_message.config(text="タスク名が空です。入力してください。")
return
tasks.append(text)
entry_task.delete(0, tk.END)
label_message.config(text=f"タスク「{text}」を追加しました。")
def refresh_listbox():
listbox_tasks.delete(0, tk.END)
for task in tasks:
listbox_tasks.insert(tk.END, task)
def delete_task():
selection = listbox_tasks.curselection()
if not selection:
label_status.config(text="削除するタスクを選択してください。")
return
index = selection[0]
task = tasks[index]
result = messagebox.askokcancel("確認", f"「{task}」を削除しますか?")
if not result:
label_status.config(text="削除をキャンセルしました。")
return
del tasks[index]
refresh_listbox()
label_status.config(text=f"タスク「{task}」を削除しました。")
def show_input_frame():
frame_list.pack_forget()
frame_input.pack(fill="both", expand=True)
def show_list_frame():
frame_input.pack_forget()
refresh_listbox()
frame_list.pack(fill="both", expand=True)
root = tk.Tk()
root.title("タスク管理アプリ")
frame_menu = tk.Frame(root)
frame_menu.pack(fill="x")
button_to_input = tk.Button(frame_menu, text="タスク入力", command=show_input_frame)
button_to_input.pack(side="left", padx=5, pady=5)
button_to_list = tk.Button(frame_menu, text="タスク一覧", command=show_list_frame)
button_to_list.pack(side="left", padx=5, pady=5)
frame_input = tk.Frame(root)
label_task = tk.Label(frame_input, text="タスク名:")
label_task.grid(row=0, column=0, padx=5, pady=5, sticky="e")
entry_task = tk.Entry(frame_input, width=30)
entry_task.grid(row=0, column=1, padx=5, pady=5)
button_add = tk.Button(frame_input, text="追加", command=add_task)
button_add.grid(row=0, column=2, padx=5, pady=5)
label_message = tk.Label(frame_input, text="タスク名を入力して「追加」を押してください。")
label_message.grid(row=1, column=0, columnspan=3, pady=10)
frame_list = tk.Frame(root)
label_list_title = tk.Label(frame_list, text="タスク一覧")
label_list_title.pack(pady=5)
listbox_tasks = tk.Listbox(frame_list, height=8, width=40)
listbox_tasks.pack(padx=10, pady=5)
button_delete = tk.Button(frame_list, text="選択したタスクを削除", command=delete_task)
button_delete.pack(pady=5)
label_status = tk.Label(frame_list, text="タスクを選択して「削除」を押してください。")
label_status.pack(pady=5)
frame_input.pack(fill="both", expand=True)
root.mainloop()
Pythonこの1ファイルの中に、
7日間で学んだ GUI 基礎とボタンイベントのエッセンスが
ほぼ全部入っています。
7日目で絶対に押さえてほしい本質
「画面」「データ」「ボタン」が一本の線でつながった状態
ここまで来たあなたはもう、
画面(Frame / Label / Entry / Listbox)を設計できる
データ(リストや変数)をどこに持つか決められる
ボタンで「いつ」「何を」「どう変えるか」を考えられる
というところまで来ています。
今日のタスク管理アプリで、
特に意識してほしいのはこの3つです。
データの本体は tasks にある(画面はあくまで表示)
画面切り替えは Frame の表示・非表示で行う
ボタンは「データの変更」と「画面の更新」の両方を担当する
この感覚が身につけば、
あとは「何を作りたいか」を決めるだけで、
tkinter でかなりいろいろなアプリが作れるようになります。
ここから先は、あなたの番です。
タスクに期限を付けてみる
優先度を付けて並び替えてみる
JSON 保存アプリで学んだ保存機能を組み合わせてみる
どれも、もう十分に手が届く範囲です。
「自分の生活で本当に使いたい小さなツール」を、
一つだけでいいので、tkinter で形にしてみてください。
そこから先が、本当の“自分のプログラミング”になっていきます。

