「日経ソフトウェア2022年9月号 特集2 Python デスクトップアプリを作ろう」を実行してみました。
サンプルプログラム
サンプルプログラムは日経ソフトウェアのWebからダウンロードできます。
以下URLから「本誌バックナンバーを見る」→「2022年9月号」→「「特集2 Pythonでデスクトップアプリを作ろう 前編」(t22209.zip))」
nkbp.jp
PART3 「割り勘計算機」アプリを作ろう
割り勘アプリを作成し、Frameウィジェット、Comboboxウィジェットの使用方法を理解していきます。
また、「割り勘計算機」の機能は以下の通りです。
・1円単位、10円単位の支払はない
・偉い人は新人の3倍、平社員の2倍の支払
・金額によっては漢字は平社員よりも少し安くする
2つの画面を切り替える
画面を切り替えるにはFrameウィジェットを使用します。
サンプルコードは以下の通りです。
・importでtkinterモジュールの呼び出し
・2フレーム間を行き来できるようにそれぞれのフレームにボタンを用意
・rootという名前のオブジェクトを作成し、サイズは250px x 100px
・ウィンドウに表示されるタイトルは「tkrasize Test」
・column(列)とrow(行)に対してそれぞれweight=1
・tk.Frameを使用してrootオブジェクトにフレームを生成
・FrameにLabelとButtonを付加
・同じようにframe_2を生成
・tkraise関数を使用することでframe_1を最前に
# button_1のハンドラ関数
def change_no2():
frame_2.tkraise() # frame_2を前面に出す
# button_2のハンドラ関数
def change_no1():
frame_1.tkraise() # frame_1を前面に出す
root = tk.Tk()
root.geometry('250x100')
root.title('tkraise Test')
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
# 画面1(frame_1)の生成と配置
frame_1 = tk.Frame(root)
frame_1.grid(row=0, column=0, sticky=tk.NSEW)
label_1 = tk.Label(frame_1, text='画面1です。')
button_1 = tk.Button(frame_1, text='次の画面',
command=change_no2)
label_1.pack(pady=10)
button_1.pack(pady=10)
# 画面2(frame_2)の生成と配置
frame_2 = tk.Frame(root)
frame_2.grid(row=0, column=0, sticky=tk.NSEW)
label_2 = tk.Label(frame_2, text='画面2です。')
button_2 = tk.Button(frame_2, text='戻る',
command=change_no1)
label_2.pack(pady=10)
button_2.pack(pady=10)
# frame_1を前面に出す
frame_1.tkraise()
root.mainloop()
実行結果
「次の画面」ボタンを押すと「画面2です。」が表示されます。
「戻る」ボタンを押すと「画面1です。」が表示されます。
Comboboxウィジェットを使用する場合は、ttkをimportする必要があります。
以下サンプルコードを見ていきますと、
・メッセージボックスをimport
・クリックしたらメッセージボックスにメッセージとしてComboboxウィジェットの内容を表示
・Comboboxウィジェットは1から5を選択可能
・それ以外の数値は直接入力可能
# Buttonのハンドラ関数
def click_get():
messagebox.showinfo('メッセージ', combo.get())
root = tk.Tk()
root.geometry('250x100')
root.title('Combo Test')
number = ['1','2','3','4','5']
combo = ttk.Combobox(root, state='normal',
values=number, width=5)
combo.current(0)
combo.pack(pady=10)
button = tk.Button(root, text='表示',
command=click_get)
button.pack()
root.mainloop()
実行結果
数値を選択し、「表示」ボタンを押すとメッセージボックスにその値が評されました。
割り勘計算機
最後に割り勘計算機アプリを起動してみます。
金額に1000を入力し計算を押すと、400円、300円、200円、100円となりました。
ベース金額=偉い人x3+平社員x2+新人+幹事(x2)なので
1000円を8で割った125円x3=375円 125円x2=250円 125円x1=125円
で、10円、1円を切り上げて400円、300円、200円となりました。残りは幹事が100円支払ってちょうど1000円です。
再計算する場合は「計算に戻る」で戻ります。
import math
# 計算結果の表示
def calculation_result():
t = int(total.get())
e = int(erai.get())
h = int(hira.get())
s = int(shin.get())
kanj = 2
base = math.floor(t / (e * 3 + h * 2 + s + kanj))
print("base ",base)
mErai = 0 if e == 0 else (math.ceil(base*3/100) * 100)
mHira = 0 if h == 0 else (math.ceil(base*2/100) * 100)
mShin = 0 if s == 0 else (math.ceil(base*1/100) * 100)
mKanj = base * kanj
total2 = mErai * e + mHira * h + mShin * s + mKanj
mKanj = mKanj - (total2 - t)
c = [['偉い人は :', str(mErai)],
['平社員は :', str(mHira)],
['新人は :', str(mShin)],
['幹事は :', str(mKanj)]]
for i in range(len(out_label)):
out_label[i][0]['text'] = c[i][0]
out_label[i][1]['text'] = c[i][1]
out_frame.tkraise() # 計算結果画面へ切り替え
def change_in():
in_frame.tkraise() # 入力画面へ切り替え
root = tk.Tk()
root.geometry('300x220')
root.title('割り勘計算機')
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
# 入力画面用フレームの生成と配置
in_frame = tk.Frame(root)
in_frame.grid(row=0, column=0, sticky=tk.NSEW)
total = tk.Entry(in_frame, width=10)
s = ('金 額( 円 )', '偉い人(人数)',
'平社員(人数)', '新 人(人数)',
'幹 事(1人)')
in_label=
for i in range(len(s)):
in_label.append(tk.Label(in_frame, text=s[i]))
number = ('1', '2', '3', '4', '5',
'6', '7', '8', '9', '10')
erai = ttk.Combobox(in_frame, values=number, width=8)
erai.current(0)
hira = ttk.Combobox(in_frame, values=number, width=8)
hira.current(0)
shin = ttk.Combobox(in_frame, values=number, width=8)
shin.current(0)
button = tk.Button(in_frame, text='計算',
command=calculation_result)
for i in range(2):
in_frame.columnconfigure(i, weight=1)
for i in range(6):
in_frame.rowconfigure(i, weight=1)
in_label[0].grid(column=0, row=0)
total.grid(column=1, row=0)
in_label[1].grid(column=0, row=1)
erai.grid(column=1, row=1)
in_label[2].grid(column=0, row=2)
hira.grid(column=1, row=2)
in_label[3].grid(column=0, row=3)
shin.grid(column=1, row=3)
in_label[4].grid(column=0, row=4, rowspan=2 )
button.grid(column=1, row=5, sticky=tk.N)
# 計算結果画面用フレームの生成と配置
out_frame = tk.Frame(root)
out_frame.grid(row=0, column=0, sticky=tk.NSEW)
out_frame.columnconfigure(0, weight=1)
out_frame.columnconfigure(1, weight=1)
for i in range(5):
out_frame.rowconfigure(i, weight=1)
out_label =
for i in range(4):
out_label.append([tk.Label(out_frame, padx=20),
tk.Label(out_frame, padx=20)])
button = tk.Button(out_frame, text='計算に戻る',
command=change_in)
for i in range(len(out_label)):
out_label[i][0].grid(column=0, row=i, sticky=tk.E)
out_label[i][1].grid(column=1, row=i, sticky=tk.W)
button.grid(column=0, row=4, columnspan=2, sticky=tk.N)
# frameを前面にする
in_frame.tkraise()
root.mainloop()