TkinterでGUIアプリ開発 03 Hello worldアプリを作る【Python3】

Python

今回は、Tkinterを使ったGUIアプリ開発の第3回、いよいよ実際に動くものを作っていきます。

作成するアプリはこちら!

ログインフォーム的なアプリを作成していきます。

ラジオボタンの選択と、入力フォームの値によって出力を変化させるシンプルなアプリです。

アプリの概要

アプリは、入力フォームに名前を入れて、コース名によって出力が変化するだけのシンプルなものです。

今回のアプリの応用先としては、ログインフォームなどでしょうか。

ユーザー名と、所属コースなどを入力して、裏のIDデータベースと照合してログインできたら別のウインドウが立ち上がる…などを考えましたが、デスクトップアプリでログインが必要なのかは微妙です。

動作としては、以下の画像のように、デフォルトでは笑顔のアイコンが表示されています。

ラジオボタンのチェックを変更すると、ボタンクリック後のテキスト表示が変化します。

構成要素

  • ボタン(Button)
  • ラベル(Label)
  • ラジオボタン(Radiobutton)
  • 画像表示(PhotoImage)

コードと留意点

以下では、ソースコードを追加していく形で、アプリを作成していきましょう。

ウィンドウの作成

まずはウィンドウを作成します。

メインのウィンドウは tkinter.Tk() なので root と定義します。

ウィンドウの設定は、root.〇〇でタイトルやアイコン、ウィンドウサイズなどを定義します。

ここで、ウィンドウやフレームの色を定義しておくと、すっきりした見た目になるのでおすすめです。

また、色のセンスがない私のような人は、勝手に配色をやってくれるサイトがあるので、参考にするとよいでしょう。

# tkinter_basic_08_hello_gui_world_01.py
import tkinter

# windowの定義
root = tkinter.Tk()
root.title("hello_gui_world")
root.iconbitmap("favicon.ico")
root.geometry("400x400")
root.resizable(0,0)

# フォントとカラーの定義
# センスある配色ができるサイト https://coolors.co/
root_color = "#2A9D8F"
input_color = "#E9C46A"
output_color = "#E76F51"
root.config(bg = root_color)

###########
### この間に機能を追加していく
###########

# rootの実行
root.mainloop()

The super fast color schemes generator!

フレーム、テキストボックス、ボタンの作成

次はフレームと、テキストボックス、ボタンを描画します。

今回のアプリでは、入力用のフレームと出力用のフレームをそれぞれ作成します。

名前をわかりやすくしておかないと、後々混同してしまうため、具体的な名前がおすすめです。

padxやpadyで余白を維持し、fill = BOTH, expand = Trueでウィンドウのサイズまで広げます。ここで、フレームの大きさなどを数値で与えてしまうと、ウィンドウのサイズを変えたときにレイアウトが崩れてしまいます。

この辺りは、テンプレートとしてコピペしてしまっていいと思います。

テキストボックスはEntryで定義できます。

textで初期値を入力します。

最後にボタンです。現状ではクリック時の関数を定義していないため、ボタンを押しても何も起きません。

commandの定義を忘れないように、コメントアウトを残しておきます。

# tkinter_basic_08_hello_gui_world_02.py
import tkinter
from tkinter import BOTH, StringVar

# windowの定義
root = tkinter.Tk()
root.title("hello_gui_world")
root.iconbitmap("favicon.ico")
root.geometry("400x400")
root.resizable(0,0)

# フォントとカラーの定義
# センスある配色ができるサイト https://coolors.co/
root_color = "#2A9D8F"
input_color = "#E9C46A"
output_color = "#E76F51"
root.config(bg = root_color)

###########
# define layout
# define frames
input_frame = tkinter.LabelFrame(root, bg =input_color)
input_frame.pack(padx = 10, pady = 10, fill = BOTH, expand = True)
output_frame = tkinter.LabelFrame(root, bg =output_color)
output_frame.pack(padx = 10, pady = 10, fill = BOTH, expand = True)

# create wigit
name = tkinter.Entry(input_frame, text = "Entry your name", width = 20)
name.grid(row = 1, column = 0, padx = 10, pady = 10)

submit_button = tkinter.Button(input_frame, text = "Submit your name", width = 20)
submit_button.config() # command = submit_name
submit_button.grid(row = 1, column = 1, padx = 10, pady = 10)
###########

# rootの実行
root.mainloop()

ラジオボタンの作成

次はラジオボタンを作成します。

コードは、これまで書いてきたものの、真下に配置してください。

ラジオボタンを選択した際に、値を取得しなければなりません。

ここではテキスト情報なので、StrigVar()を指定します。

また、value = 〇〇でStringVar()に渡す情報を定義します。

↑これでラジオボタンのテキスト情報を取得します。

# tkinter_basic_08_hello_gui_world_03.py
# create radio button for text display
case_style = StringVar()
# ラジオボタンのデフォルト
case_style.set("normal")
normal_button = tkinter.Radiobutton(input_frame, text = "Normal Case")
normal_button.config(variable = case_style, value = "normal",bg =input_color)
normal_button.grid(row = 0, column = 0, padx = 5, pady = 5)

upper_button = tkinter.Radiobutton(input_frame, text = "Upper Case")
upper_button.config(variable = case_style, value = "Upper",bg =input_color)
upper_button.grid(row = 0, column = 1, padx = 5, pady = 5)

画像の表示

次は画像を表示します。

ここの画像はなんでもいいですが、ウィンドウに表示するので小さめの画像を用意するのがおすすめです。

画像の出力には、PILから、ImageTkとImageのインポートが必要です。

# tkinter_basic_08_hello_gui_world_04.py
from PIL import ImageTk,Image
# add an image
smile_img = ImageTk.PhotoImage(Image.open("smile.png"))
smile_label = tkinter.Label(output_frame, image = smile_img, bg = output_color)
smile_label.pack()

ここまでで、見た目はそれっぽくできましたが、まだボタンを押しても何も起きません。

最後は、ボタンに機能を付与しましょう。

機能の追加

ボタンクリック時の関数を定義します。

コードは、ウィンドウ定義とフレーム定義の間に書きます。

関数を実行する場所よりも前に設置しないと、エラーになってしまいます。

コードの内容は、ラジオボタンとテキストボックスの値によって、出力するテキストを変化させるものです。

まずは、ラジオボタンによって処理を分岐します。

case_style.get()でラジオボタンの値を取り出します。

その後は、テキストボックス内部の値をname.get()で取り出し、出力すれば完成です。

また、最後の行のname.delete(0, END)は、ボタンをクリックするとテキストボックスの入力値をリセットするというコードになっています。

# tkinter_basic_08_hello_gui_world_05.py
# define function
def submit_name():
    # ラジオボタンによって処理を分岐する
    if case_style.get() == "normal":
        output_label = tkinter.Label(output_frame)
        output_label.config(text = "Hello " + name.get() + " Your course is Normal", bg =output_color)
        
    else:
        output_label = tkinter.Label(output_frame)
        output_label.config(text = "Hello " + name.get() + " Your course is Upper", bg =output_color)
    output_label.pack()
    name.delete(0, END)

ソースコード全体

最後にコードの全体を張っておきます。

上記の説明だけでは、エラーが出る…という方は参考にしてください。

# tkinter_basic_08_hello_gui_world.py
# hello gui world

import tkinter
from tkinter import BOTH, StringVar
from PIL import ImageTk,Image
from tkinter import END

# windowの定義
root = tkinter.Tk()
root.title("hello_gui_world")
root.iconbitmap("favicon.ico")
root.geometry("400x400")
root.resizable(0,0)

# フォントとカラーの定義
# センスある配色ができるサイト https://coolors.co/
root_color = "#2A9D8F"
input_color = "#E9C46A"
output_color = "#E76F51"
root.config(bg = root_color)

# define function
def submit_name():
    # ラジオボタンによって処理を分岐する
    if case_style.get() == "normal":
        output_label = tkinter.Label(output_frame)
        output_label.config(text = "Hello " + name.get() + " Your course is Normal", bg =output_color)
        
    else:
        output_label = tkinter.Label(output_frame)
        output_label.config(text = "Hello " + name.get() + " Your course is Upper", bg =output_color)
    output_label.pack()
    name.delete(0, END)

# define layout
# define frames
input_frame = tkinter.LabelFrame(root, bg =input_color)
input_frame.pack(padx = 10, pady = 10, fill = BOTH, expand = True)
output_frame = tkinter.LabelFrame(root, bg =output_color)
output_frame.pack(padx = 10, pady = 10, fill = BOTH, expand = True)

# create wigit
name = tkinter.Entry(input_frame, text = "Entry your name", width = 20)
name.grid(row = 1, column = 0, padx = 10, pady = 10)

submit_button = tkinter.Button(input_frame, text = "Submit your name", width = 20)
submit_button.config(command = submit_name)
submit_button.grid(row = 1, column = 1, padx = 10, pady = 10)

# create radio button for text display
case_style = StringVar()
# ラジオボタンのデフォルト
case_style.set("normal")
normal_button = tkinter.Radiobutton(input_frame, text = "Normal Case")
normal_button.config(variable = case_style, value = "normal",bg =input_color)
normal_button.grid(row = 0, column = 0, padx = 5, pady = 5)

upper_button = tkinter.Radiobutton(input_frame, text = "Upper Case")
upper_button.config(variable = case_style, value = "Upper",bg =input_color)
upper_button.grid(row = 0, column = 1, padx = 5, pady = 5)

# add an image
smile_img = ImageTk.PhotoImage(Image.open("smile.png"))
smile_label = tkinter.Label(output_frame, image = smile_img, bg = output_color)
smile_label.pack()

# rootの実行
root.mainloop()

まとめ

今回は、TkinterでHello Worldをやってみました。

テキストを表示するだけの簡単な処理ですが、値を渡したり、GUIアプリ特有の動作がいくつか出てきました。

入力の値やラジオボタンのチェックの違いによって別のウィンドウを出したりと、複雑な処理に分岐していくことも可能です。

次回は、単位変換アプリの作成を予定しているので、更新までお待ちください。