pythonのtkinterでGUI画面を作成する【CHATGPT】

a green square with a white knot on it ChatGPT

※この記事は、記事の精度の調査と自分の学習と効率化のために、ChatGPTに書いてもらったものをベースとしています。

画像と赤文字で記載されている箇所などは私のコメントや感想部分です。

はじめに

tkinterウィジェットの概要

tkinterは、Pythonの標準GUIライブラリの一部として提供されています。このライブラリは、ネイティブなルックアンドフィールを持つデスクトップアプリケーションを作成するためのツールキットを提供しており、その中心となるのがウィジェットです。ウィジェットは、ボタンやテキストボックス、ラベルなどのGUIコンポーネントを指します。これらのウィジェットを組み合わせることで、ユーザーとのインタラクションを持つアプリケーションを作成することができます。

この記事の目的と対象読者

本記事の目的は、tkinterの主要なウィジェットを紹介し、それぞれの基本的な使用方法や特徴を明らかにすることです。初心者向けに基本から解説を行い、中級者の方にも役立つ情報を提供することを目指しています。

対象とする読者は以下の通りです:

  • Pythonをある程度知っているが、tkinterにはまだ慣れていない初心者の方。
  • GUIアプリケーションの作成に興味がある方。
  • tkinterでのアプリケーション開発を効率化したい中級者の方。

次のセクションから、具体的なウィジェットの紹介とその使用方法について解説していきます。お楽しみに!

基本的なウィジェット

ラベル (Label)

ラベルは、テキストや画像を表示するためのウィジェットです。ユーザーとのインタラクションは持たないため、情報を表示するだけの場合に使います。

基本的な使用方法:
import tkinter as tk

root = tk.Tk()
label = tk.Label(root, text="Hello, tkinter!")
label.pack()
root.mainloop()

このコードは、”Hello, tkinter!”というテキストを持つラベルを作成します。

テキストとスタイルのカスタマイズ:

ラベルのテキストは、text属性で変更可能です。また、fontfg(前景色)、bg(背景色)などの属性を用いてスタイルをカスタマイズできます。

label = tk.Label(root, text="Styled Label", font=("Arial", 12, "bold"), fg="blue", bg="yellow")

ボタン (Button)

ボタンは、クリックなどのアクションを受け取るウィジェットです。ユーザーの操作に応じて特定の動作をトリガーする場合に使用します。

基本的な使用方法:
def on_button_click():
    print("Button clicked!")

button = tk.Button(root, text="Click Me!", command=on_button_click)
button.pack()
コマンド(イベント)の割り当て:

上記の例では、on_button_click関数がボタンクリック時に実行されるように設定しています。これは、command属性に関数を割り当てることで実現しています。

エントリ (Entry)

エントリは、一行のテキスト入力を受け取るウィジェットです。ユーザーからの短いテキスト情報(例:ユーザー名やパスワード)を取得する場合に使用します。

テキスト入力の受け取り:
entry = tk.Entry(root)
entry.pack()

def get_entry_text():
    print(entry.get())

button = tk.Button(root, text="Submit", command=get_entry_text)
button.pack()

上記の例では、エントリからテキストを取得し、コンソールに表示します。

バリデーションの追加:

エントリには、入力のバリデーションを追加することもできます。例えば、数字のみを受け付けるような制約を追加することが可能です。

def validate_input(char):
    return char.isdigit()

validate_command = root.register(validate_input)
entry = tk.Entry(root, validate="key", validatecommand=(validate_command, '%S'))
entry.pack()

このセクションでは、基本的なウィジェットとその使用方法を簡潔に紹介しました。詳細や応用的な使用方法については、それぞれのウィジェットの公式ドキュメントを参照することをおすすめします

実際に作成と操作してみた

GPT先生が紹介してくれたラベル・ボタン・エントリの3ウィジェットとカスタマイズ情報使用して、ログインフォーム画面を作成してみましょう。

イメージとしては

ログイン画面
ユーザー名: 入力欄
パスワード: 入力欄
送信ボタン

↑ こんな感じになるようになってみます

import tkinter as tk

def on_button_click():
    user = get_entry_user_text()
    passwd = get_entry_password_text()
    print(f"送信されました!\nユーザー:{user} パスワード:{passwd}")
    
def get_entry_user_text():
    return entry_user.get()

def get_entry_password_text():
    return entry_passwd.get()

def validate_input(char):
    return char.isdigit()

root = tk.Tk()

label_user = tk.Label(root, text="ユーザー名:", font=("Arial", 12, "bold"), fg="white", bg="light blue")
label_user.pack()

entry_user = tk.Entry(root)
entry_user.pack()

validate_command = root.register(validate_input)

label_passwd = tk.Label(root, text="パスワード:", font=("Arial", 12, "bold"), fg="white", bg="light blue")
label_passwd.pack()

entry_passwd = tk.Entry(root, validate="key", validatecommand=(validate_command, '%S'))
entry_passwd.pack()

button = tk.Button(root, text="送信ボタン", command=on_button_click)
button.pack()

root.mainloop()

上記コードは
・パスワードのエントリには数値しか受け付けない処理
・送信ボタンを押すとコンソールに”送信されました!”という文字列と、記載したユーザー名とパスワードを表示する

画面を作成しました。
先生の教えだけで基本ウィジェットは完璧ですね!

選択系ウィジェット

チェックボタン (Checkbutton)

チェックボタンは、選択と非選択の二つの状態を持つウィジェットです。複数のオプションからいくつかを選択する際に使います。

単一・複数選択の方法:
import tkinter as tk

root = tk.Tk()
var1 = tk.IntVar()
var2 = tk.IntVar()

chk1 = tk.Checkbutton(root, text="Option 1", variable=var1)
chk2 = tk.Checkbutton(root, text="Option 2", variable=var2)

chk1.pack()
chk2.pack()
root.mainloop()

上記の例では、二つのチェックボタンを表示しており、それぞれ独立して選択できます。

ラジオボタン (Radiobutton)

ラジオボタンは、複数のオプションから一つだけを選択するウィジェットです。

グループ化と選択:
selected_var = tk.StringVar()

rb1 = tk.Radiobutton(root, text="Choice 1", variable=selected_var, value="choice1")
rb2 = tk.Radiobutton(root, text="Choice 2", variable=selected_var, value="choice2")

rb1.pack()
rb2.pack()

この例では、二つのラジオボタンが同じStringVarオブジェクトに関連付けられているため、一つしか選択できません。

リストボックス (Listbox)

リストボックスは、複数の項目から一つまたは複数を選択するウィジェットです。

複数の選択肢からの選択:
listbox = tk.Listbox(root)
listbox.insert(1, "Item 1")
listbox.insert(2, "Item 2")
listbox.insert(3, "Item 3")
listbox.pack()

この例では、三つの項目を持つリストボックスを表示しています。

リストアイテムの追加と削除:
# アイテムの追加
listbox.insert(tk.END, "Item 4")

# アイテムの削除
listbox.delete(0)  # 最初の項目を削除

insertメソッドで新しいアイテムを追加し、deleteメソッドでアイテムを削除できます。

以上が、選択系ウィジェットの基本的な使用方法と特徴になります。各ウィジェットにはさらに多くのオプションや機能がありますので、具体的なニーズに合わせて公式ドキュメントなどの詳細情報を参照してください。

実際に作成と操作してみた

お次は選択系ウィジェットですね。
チェックボタン・ラジオボタン・リストボックスと追加情報を使用して、先程のログインフォームをアップデートして、登録フォームとして編集します

import tkinter as tk

def on_button_click():
    entries = get_entries()
    print(f"送信されました!\nユーザー:{entries['entry_user']} パスワード:{entries['entry_passwd']}")
    print(f"メルマガを受け取る: {'受け取る' if entries['var1']==1 else '受け取らない'}\n性別: {entries['selected_var']}\n出身地: {entries['listbox']}")

def get_entries():
    return {
        "entry_user":entry_user.get(),
        "entry_passwd":entry_passwd.get(),
        "var1":var1.get(),
        "selected_var":selected_var.get(),
        "listbox": listbox.get(listbox.curselection()[0])
    }

def validate_input(char):
    return char.isdigit()

root = tk.Tk()

label_user = tk.Label(root, text="ユーザー名:", font=("Arial", 12, "bold"), fg="white", bg="light blue")
label_user.pack()

entry_user = tk.Entry(root)
entry_user.pack()

validate_command = root.register(validate_input)

label_passwd = tk.Label(root, text="パスワード:", font=("Arial", 12, "bold"), fg="white", bg="light blue")
label_passwd.pack()

entry_passwd = tk.Entry(root, validate="key", validatecommand=(validate_command, '%S'))
entry_passwd.pack()

label_merumaga = tk.Label(root, text="メルマガ:", font=("Arial", 12, "bold"), fg="yellow", bg="light green")
label_merumaga.pack()

var1 = tk.IntVar()
chk1 = tk.Checkbutton(root, text="メルマガを受け取る", variable=var1)
chk1.pack()

label_gender = tk.Label(root, text="性別:", font=("Arial", 12, "bold"), fg="yellow", bg="light green")
label_gender.pack()
selected_var = tk.StringVar()
selected_var.set("male")

rb1 = tk.Radiobutton(root, text="", variable=selected_var, value="male")
rb2 = tk.Radiobutton(root, text="", variable=selected_var, value="female")

rb1.pack()
rb2.pack()

label_from = tk.Label(root, text="出身地:", font=("Arial", 12, "bold"), fg="yellow", bg="light green")
label_from.pack()

listbox = tk.Listbox(root)
listbox.insert(1, "北海道")
listbox.insert(2, "東京")
listbox.insert(3, "沖縄")
listbox.pack()

button = tk.Button(root, text="送信ボタン", command=on_button_click)
button.pack()

root.mainloop()

結果は以下

セレクトボックスはそのままだとデフォルトで2つ選択されてしまうので

selected_var.set("male")

としてデフォルトで男を選択するようにしています。

またlistboxは複数選択の設定もあるので、データを取得するとき

listbox.curselection()

として帰ってくるタプルの先頭のインデックスをgetで取得します。
また結果取得はまとめてget_entries関数に変更しました。

高度なウィジェット

スライダー (Scale)

スライダーは、連続した数値の範囲から一つの値を選択するためのウィジェットです。

値の範囲設定:
slider = tk.Scale(root, from_=0, to=100, orient=tk.HORIZONTAL)
slider.pack()

上記の例では、0から100の範囲のスライダーを水平方向に表示しています。

テキストボックス (Text)

テキストボックスは、複数行のテキストを入力・表示するためのウィジェットです。

複数行のテキスト入力:
textbox = tk.Text(root, height=5, width=30)
textbox.pack()
テキストの操作と検索:
# テキストの追加
textbox.insert(tk.END, "This is a sample text.")

# テキストの検索
index = textbox.search("sample", tk.START, tk.END)
print("Found at:", index)

キャンバス (Canvas)

キャンバスは、図形や画像などのグラフィックスを描画するためのウィジェットです。

基本的な図形の描画:
canvas = tk.Canvas(root, width=300, height=200)
canvas.pack()

# 四角形の描画
canvas.create_rectangle(50, 50, 150, 150, fill="blue")

# 円の描画
canvas.create_oval(200, 50, 250, 100, fill="red")
イベントの取り扱い:
def on_canvas_click(event):
    print("Clicked at", event.x, event.y)

canvas.bind("<Button-1>", on_canvas_click)

上記の例では、キャンバスをクリックした位置の座標をコンソールに表示しています。

これで、「高度なウィジェット」に関する基本的な情報と使用方法を紹介しました。各ウィジェットにはさらに詳細なオプションや機能が存在するため、具体的な実装やカスタマイズを行う際には公式ドキュメントや関連リソースを参照すると良いでしょう。

実際に作成と操作してみた

今度は高度なウィジェットということで、ちょっと身構えてしまいそうですがどうでしょうか。
私はすべて使ったことはあるものの特にキャンバスの設定系がいまいち理解が出来ていないと思います。

では先生が作成したキャンパスを用いて、
青い四角を防御ボタン、赤い丸が攻撃ボタンと見立てて処理を作成しましょう。
そして実行されたボタンをtextboxに防御か攻撃かログとして残していきます。
このとき、一定の確率で必殺技が出るとします。
縦のスライダーを操作すると防御で必殺技が出る確率を横のスライダーを操作すると攻撃の必殺技の確率を操作します。共に確率は設定数値により1000分の1から10分の1とします
そしてとにかく連打しますので、確認ボタンでログから必殺技が出たかどうか確認するようにします

def get_hissatu(value):
    return random.randint(1, 1000) in range(value)

def on_canvas_click(event):
    if sikaku_pos[0] <= event.x <= sikaku_pos[2] and sikaku_pos[1] <= event.y <= sikaku_pos[3] :
        waza = "防御!"
        if get_hissatu(slider1.get()):
            waza = "必殺カウンター!!!"
        textbox.insert(tk.END, waza)
    elif maru_pos[0] <= event.x <= maru_pos[2] and maru_pos[1] <= event.y <= maru_pos[3] :
        waza = "攻撃!"
        if get_hissatu(slider2.get()):
            waza = "必殺連打!!!"
        textbox.insert(tk.END, waza)

def on_button_click():
    index = textbox.search("必殺", 0.0, tk.END)
    print("Found at:", index)

root = tk.Tk()

slider1 = tk.Scale(root, from_=1, to=100, orient=tk.VERTICAL, sliderrelief=tk.RAISED, borderwidth=10,troughcolor="blue")
slider1.pack()

slider2 = tk.Scale(root, from_=1, to=100, orient=tk.HORIZONTAL, sliderrelief=tk.RAISED, borderwidth=10,troughcolor="blue")
slider2.pack()

canvas = tk.Canvas(root, width=400, height=200)
canvas.pack()
canvas.bind("<Button-1>", on_canvas_click)

sikaku_pos = (50, 50, 150, 150)
maru_pos = (200, 50, 300, 150)
# 四角形の描画
canvas.create_rectangle(sikaku_pos, fill="blue")

# 円の描画
canvas.create_oval(maru_pos, fill="red")

textbox = tk.Text(root, height=5, width=30)
textbox.pack()

button = tk.Button(root, text="確認ボタン", command=on_button_click)
button.pack()

root.mainloop()

動作確認していたらふと思った

何やってんだ俺は??

先生が作った丸四角のがゲームコントローラにでも見えたのだろう。。

とりあえずtextboxの位置情報がfloat型で、いまいちよくわからんの今度調査する必要があるということだけは間違いない

あとは先生が作成したtk.STARTというものはなかったので注意!

その他の便利なウィジェット

オプションメニュー (OptionMenu)

オプションメニューは、ドロップダウンリストから選択するためのウィジェットです。

selected_option = tk.StringVar(root)
selected_option.set("Option 1")  # デフォルト値

options = ["Option 1", "Option 2", "Option 3"]
option_menu = tk.OptionMenu(root, selected_option, *options)
option_menu.pack()

スピンボックス (Spinbox)

スピンボックスは、指定された範囲の数値やリストから値を選択するためのウィジェットです。

spinbox = tk.Spinbox(root, from_=1, to=10)
spinbox.pack()

フレーム (Frame)

フレームは、他のウィジェットをグループ化するコンテナとして使用されます。フレーム自体は視覚的にはほとんど目立ちませんが、内部のウィジェットを整理するのに役立ちます。

frame = tk.Frame(root, bg="lightgray", padx=10, pady=10)
frame.pack(padx=20, pady=20)

label_in_frame = tk.Label(frame, text="This is inside the frame!")
label_in_frame.pack()
ウィジェットのグループ化と整理:

フレームを使用すると、ウィジェットをセクションごとに整理して配置することができます。これにより、UIのデザインが整ったものになり、ユーザビリティが向上します。

これで、「その他の便利なウィジェット」に関する基本的な情報と使用方法を紹介しました。これらのウィジェットを効果的に利用することで、GUIアプリケーションの機能性や見た目を向上させることができます。

OptionMenuというものがあるのは初めて知りました。

これは画面の整理整頓に便利ですね!今度使ってみよう

まとめ

これまでの内容の総括

本記事では、tkinterを使用したGUI開発における主要なウィジェットに焦点を当て、その基本的な使用方法と特徴について解説しました。基本的なウィジェット(ラベル、ボタン、エントリなど)から、選択系、高度なウィジェット、その他の便利なウィジェットまで、幅広く取り上げました。これらのウィジェットを組み合わせることで、多様な機能を持つアプリケーションを作成することができます。

次回予告や関連記事へのリンク

次回の記事では、tkinterの高度なレイアウト管理やイベント駆動プログラミングについて詳しく解説します。また、tkinterを使った実際のアプリケーション開発のヒントやトリックも紹介予定です。お楽しみに!

最後に

以上がCHATGPT先生が作成してくれた記事になります。

ところどころミスや情報が古いものもあるけど、流石ですね。自分の文章より見やすいし

説明がうまい!また次の記事も先生に書いてもらって投稿主もお勉強をしていきたいと思います。

以上

tkinterを使用したGUIツールの作成も結構、請け負っているのでご相談ください!

次の記事
タイトルとURLをコピーしました