GUIアプリの概要
以前投稿したアプリを改修したのでそれを共有したいと思います。
以前投稿したアプリは以下の記事になります。
ttkbootstarpのGoogle検索をしたら二番目にヒットします。
是非合わせてお読み下さい。
改良点
ソースコードをクラスで作成
QRコードの作成を自分で指定した場所に作成できるように改修
日記を書けるように改修
アプリ概要
QRコード
勤怠計算
日記
Tab Two
Windowsカラー変更
基本設計書
1. 概要
このプログラムは、Tkinterを使用してGUIアプリケーションを作成するためのサンプルです。主な機能としては、QRコードの生成、勤怠計算、日記の保存、日付とウィンドウの色の変更があります。
ttkbootstarapで使用できる機能をまとめて実装しています。
2. 機能要件
①QRコードの生成
②勤怠計算
③日記の保存
④日付の取得
⑤ウィンドウの色の変更
3. クラス構造
- Application: GUIアプリケーションのメインクラス
- qr_create(): QRコード生成タブの作成
- attendance(): 勤怠計算タブの作成
- Tab_one(): 日記タブの作成
- Tab_Two(): タブ2の作成
- Window_change(): ウィンドウの色変更タブの作成
- main(): アプリケーションの実行を開始するメソッド
4. メソッド仕様
- qr_create():
- QRコード生成ボタンをクリックすると、入力されたURLからQRコードを生成し、保存する
- attendance():
- 勤怠計算ボタンをクリックすると、出勤時間、退勤時間、休憩時間から労働時間を計算する
- Tab_one():
- 保存ボタンをクリックすると、入力された日記をテキストファイルに保存する
- Tab_Two():
- 日付取得ボタンをクリックすると、選択された日付を表示する
- Window_change():
- テーマを変更すると、ウィンドウの外観が変更される
ソースコード
import tkinter as tk
from tkinter import filedialog
from ttkbootstrap import (
Button,
Label,
Checkbutton,
Combobox,
DateEntry,
Menu,
Menubutton,
Notebook,
Frame,
Window,
Style,
dialogs,
)
import qrcode
from datetime import datetime
from tkinter.filedialog import asksaveasfilename
class Application:
def __init__(self, root):
self.root = root
self.root.title("Notebook")
self.root.geometry("500x400")
self.notebook = Notebook(root, bootstyle="light")
self.notebook.pack(pady=20)
self.my_date_label = Label()
self.qr_create()
self.attendance()
self.Tab_one()
self.Tab_Two()
self.Window_change()
def qr_create(self):
def btn_click():
S = self.Url_text.get()
img = qrcode.make(S)
path = asksaveasfilename(initialdir=dir)
img.save(f"{path}.png")
tab_qr = Frame(self.notebook)
self.notebook.add(tab_qr, text="QRコード作成")
self.Url_lbl = Label(tab_qr, text="URL")
self.Url_lbl.place(x=70, y=100)
self.Url_text = tk.Entry(tab_qr, width=30)
self.Url_text.place(x=130, y=100)
btn = Button(
tab_qr, text="QRコード生成", bootstyle="success", command=btn_click
)
btn.place(x=180, y=150)
def attendance(self):
def btn_click():
self.total_value.delete(0, tk.END)
start = self.start_value.get() # 出勤時間
last = self.last_value.get() # 退勤時間
rest = self.rest_value.get() # 休憩時間
FMT = "%H:%M:%S"
tdelta = datetime.strptime(last, FMT) - datetime.strptime(start, FMT)
tdelta_cgange = str(tdelta)
tdelta_1 = datetime.strptime(tdelta_cgange, FMT) - datetime.strptime(
rest, FMT
)
self.total_value.insert(0, str(tdelta_1))
def btn_clear():
self.start_value.delete(0, tk.END)
self.last_value.delete(0, tk.END)
self.rest_value.delete(0, tk.END)
self.total_value.delete(0, tk.END)
def thing():
cal = dialogs.Querybox()
self.my_date_label = Label(
tab_attendance,
text=f"日付: {cal.get_date()}",
bootstyle="inverse success",
)
self.my_date_label.place(x=5, y=10)
tab_attendance = Frame(self.notebook)
self.notebook.add(tab_attendance, text="勤怠計算")
lbl_massage = Label(tab_attendance, text="勤務時間を入力して下さい。")
lbl_massage.place(x=145, y=60)
start_lbl = Label(tab_attendance, text="出勤時間")
start_lbl.place(x=70, y=100)
last_lbl = Label(tab_attendance, text="退勤時間")
last_lbl.place(x=70, y=130)
rest_lbl = Label(tab_attendance, text="休憩時間")
rest_lbl.place(x=70, y=160)
total_lbl = Label(tab_attendance, text="労働時間")
total_lbl.place(x=70, y=190)
self.start_value = tk.Entry(tab_attendance, width=30)
self.start_value.place(x=145, y=100)
self.last_value = tk.Entry(tab_attendance, width=30)
self.last_value.place(x=145, y=130)
self.rest_value = tk.Entry(tab_attendance, width=30)
self.rest_value.place(x=145, y=160)
self.total_value = tk.Entry(tab_attendance, width=30)
self.total_value.place(x=145, y=190)
btn = Button(
tab_attendance, text="勤 怠 計 算", bootstyle="success", command=btn_click
)
btn.place(x=155, y=230)
btn = Button(
tab_attendance, text="ク リ ア", bootstyle="success", command=btn_clear
)
btn.place(x=155, y=270)
btn = Button(
tab_attendance, text="日 付 選 択", bootstyle="success", command=thing
)
btn.place(x=370, y=10)
def Tab_one(self):
def daiary():
mb = dialogs.Messagebox.okcancel("ファイルを保存しますか?")
if mb == "OK":
s = self.my_text.get(0.0, tk.END)
self.my_text.delete(0.0, tk.END)
path = filedialog.asksaveasfilename(defaultextension=".txt")
if not path:
return
with open(path, "w", encoding="utf-8") as f:
f.write(s)
tab1 = Frame(self.notebook)
self.notebook.add(tab1, text="日記")
my_label = Label(tab1, text="日記を書いてね!!", font=("Helvetica", 18))
my_label.pack(pady=20)
self.my_text = tk.Text(tab1, width=70, height=10)
self.my_text.pack(pady=10, padx=10)
my_button = Button(
tab1, text="保存", bootstyle="danger outline", command=daiary
)
my_button.pack(pady=20)
def Tab_Two(self):
tab2 = Frame(self.notebook)
self.notebook.add(tab2, text="Tab Two")
days = [
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday",
]
my_combo = Combobox(tab2, bootstyle="success", values=days)
my_combo.pack(pady=20)
my_combo.current(0)
def date_get():
self.my_date_label = Label(
tab2, text=f"日付取得: {self.my_date.entry.get()}"
)
self.my_date_label.pack(pady=10)
self.my_date = DateEntry(tab2, firstweekday=0, bootstyle="success")
self.my_date.pack(pady=20)
my_date_button = Button(
tab2, text="日付取得", bootstyle="success", command=date_get
)
my_date_button.pack(pady=10)
def Window_change(self):
tab3 = Frame(self.notebook)
self.notebook.add(tab3, text="Windowカラー変更")
val2 = tk.IntVar()
my_check = Checkbutton(
tab3,
bootstyle="success, round-toggle",
text="OK?",
variable=val2,
onvalue=1,
offvalue=0,
)
my_check.pack(pady=20)
val3 = tk.IntVar()
my_check = Checkbutton(
tab3,
bootstyle="warning, square-toggle",
text="No?",
variable=val3,
onvalue=1,
offvalue=0,
)
my_check.pack(pady=10)
# メニューラベル(Tab Three)
def stuff(x):
self.my_menu_label.config(
text=f"あなたが選んだ言語は:{x}", bootstyle="inverse success"
)
self.my_menu_label = Label(tab3, text="あなたが選んだ言語は:")
self.my_menu_label.place(x=25, y=20)
self.my_menu = Menubutton(tab3, bootstyle="success", text="メニュー")
self.my_menu.pack(pady=20)
inside_menu = Menu(self.my_menu)
item_ver = tk.StringVar()
for x in ["python", "java", "C", "PHP", "Ruby", "JavaScript", "C++"]:
inside_menu.add_radiobutton(
label=x, variable=item_ver, command=lambda x=x: stuff(x)
)
self.my_menu["menu"] = inside_menu
# テーマを変更する関数
def change_theme(event):
global style
theme = combo_var.get()
style = Style(theme=theme)
# テーマコンボボックスを作成
themes = [
"cosmo",
"flatly",
"journal",
"litera",
"lumen",
"minty",
"pulse",
"sandstone",
"united",
"yeti",
"morph",
"simplex",
"cerculean",
"solar",
"superhero",
"darkly",
"cyborg",
"vapor",
]
combo_var = tk.StringVar() # コンボボックスにデータをセットする。
combo = Combobox(tab3, values=themes, textvariable=combo_var)
combo.set("Windowの色を選択")
combo.place(x=310, y=10)
combo.bind(
"<<ComboboxSelected>>", change_theme
) # コンボボックスの選択イベントにchange_theme関数をバインド
def main(self):
self.root.mainloop()
if __name__ == "__main__":
root = Window(themename="darkly")
app = Application(root)
app.main()