@saishooo

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

python tkinter クラスについて

tkinterのクラスについて教えてください
tkinter内でのクラスの動作について教えて欲しいです。

下記の図のようなソースコードを書いています。
スクリーンショット 2025-09-02 21.28.22.png

20~47行目までがクラスの定義を行いました。
49~52行目までがmain.pyが実行された際に動く箇所だと思います。

【私が考えている流れ】
50行目ではtkinterを使用するための処理。
51行目ではappでクラスの作成処理。
52行目ではtkinterのメンループを行う処理。

52行目の"root.mainloop()により、50~52行目がひたすら繰り返されていると考えています。
繰り返すことによって、ボタンが押下されたか否かの判定などを行っている。
→ひたすらインスタンスを作成を繰り返しているという認識でいるのですが、合っていますか?

私の考えは合っていますでしょうか?

また、tkinterでクラスを使用するメリットがあまりよくわかっていません。
以前クラスを使用せずUIを作成した際に、値の扱いなどがめんどくさかったことだけ記憶にあります。
UIに変更が生じた際にクラスを使用していると、変更が楽になるとかでしょうか?
こちらについても教えていただきたいです。

0 likes

3Answer

52行目の"root.mainloop()により、50~52行目がひたすら繰り返されていると考えています。
ひたすらインスタンスを作成を繰り返しているという認識でいるのですが、合っていますか?

違います。 mainlooop()の処理ははtkinterのコードの中で定義されていて、その中で無限ループになっています。そこでは、発生したイベントの処理やGUIの更新など、GUIアプリとして必要な処理をしています。
ですので、50行目や51行目がなんども実行されているということはなく、それらで生成されたオブジェクト(インスタンス)は1度だけ生成され、メインループの実行中はそのまま存在しています。

tkinterでクラスを使用するメリットがあまりよくわかっていません。
UIに変更が生じた際にクラスを使用していると、変更が楽になるとかでしょうか?

特にメリットは無いでしょう。
通常のpythonプログラムをクラスベースで書くかどうかと同様、クラスベースで管理するのに慣れているのであれば、そうすればいいし、慣れていないのであればクラス無しで書けばいいでしょう。

1Like

Comments

  1. @saishooo

    Questioner

    ご回答ありがとうございます!
    root.mainloop()の仕様を理解しました。
    ありがとうございました!

また、tkinterでクラスを使用するメリットがあまりよくわかっていません。

クラスにするとself(インスタンス自身)に情報を格納できます。
クラスにしないとグローバル変数に格納することになります。グローバル変数は無関係な関数からも変更できたり、名前が被ったりしてバグの元になりやすいです。

関数で実装、グローバル変数使用
import tkinter as tk

def load_tasks():
    return []

def save_task(tasks):
    print(tasks)

def todo_app(root):
    global tasks, task_entry, date_entry, listbox

    root.title("ToDoリスト")
    tasks=load_tasks()

    tk.Label(root,text="タスク:").pack(anchor="w",padx=10)
    task_entry=tk.Entry(root,width=40)
    task_entry.pack(pady=5)

    tk.Label(root,text="期限を入力(例:2025-04-30").pack(anchor="w",padx=10)
    date_entry=tk.Entry(root,width=20)
    date_entry.pack(pady=5)

    add_button=tk.Button(root,text="タスクの追加",command=add_task)
    add_button.pack(pady=5)

    listbox=tk.Listbox(root,width=50,selectmode=tk.SINGLE)
    listbox.pack(pady=5)

def add_task():
    global tasks, task_entry, date_entry
    task=task_entry.get().strip()
    date=date_entry.get().strip()
    if task:
        tasks.append({"task":task,"juge":False,"date":date})
        save_task(tasks)

if __name__=="__main__":
    root=tk.Tk()
    todo_app(root)
    root.mainloop()
1Like

Comments

  1. ご回答ありがとうございます!
    初歩的なことかもしれないのですが、追加でお聞きしたいです。
    ここで言うrootとはUIのことで、それをtask_app関数に渡し、UIの設定や操作を行うと言うことであっていますか?

    rootは GUI である tkinter の処理を担当するインスタンスです。
    それを使ってUI構築(UI部品配置)やイベント処理設定(コールバック関数登録)を行ってもらうためにtodo_app関数(名前をクラス名に合わせました)に渡しています。意図が伝わりやすいように関数名は build_ui にしておけばよかったですね。
    その後、tkinter の mainloop を呼び出すと描画処理やイベント処理が行われます。
    mainloopでは、キー入力、マウス操作、タイマー終了などのイベントが発生したら登録されているコールバック関数を呼び出し、コールバック関数から戻ってきたら描画反映とイベント処理を行います(quitが呼ばれるまでループします)。
    余談ですが、mainloopがそういう処理をしているため、コールバック関数の中で時間のかかる処理をしたりsleepすると描画処理やイベント処理が止まってしまいます。

ご回答ありがとうございます!
初歩的なことかもしれないのですが、追加でお聞きしたいです。
ここで言うrootとはUIのことで、それをtask_app関数に渡し、UIの設定や操作を行うと言うことであっていますか?

0Like

Your answer might help someone💌