以前の記事でCustomTkinterを少し触りました。
↓前回の記事
勉強したものを活かして車/バイクの整備などの情報を整理するのを補助するツールを作っていきます。今回の記事ではGUIを基礎的なパーツを作成していきます。
今回作成するGUI概要図
今回作成するGUIの概要図を示します。
- 整備か給油を選択できるようにする
- バイクと車を持っているため、入力の対象がどちらか選択できるようにする
- 事象が発生した日付、Oddmeterの値、備考欄を入力できるようにする
- 給油が選択された場合に給油量、TripMeterの値、金額を入力できるようにする
- 整備が選択された場合に給油量と金額を入力できるようにする
- 入力内容を出力するファイルがあるフォルダのパスを入力できるようにする
- 入力が終わり、決定ボタンが押下されたら燃費を出力するようにする(給油選択時)
おおよその内容としては以上です。細かいところは実装しながら修正していきます。
共通項目の実装
ここからは共通項目に記載した内容についてUIを実装していきます。
ラジオボタンの実装
まず初めに今回入力する項目が給油なのか、整備なのかを選択するラジオボタンと車種を選択するラジオボタンを実装していきます。前回チュートリアルで作成したコードを修正する形で実装していきます。ラジオボタンについてですが、下記のように記述することで作成できます。
customtkinter.CTkRadioButton(master,width,height,raduobutton_width,radiobutton_height,corner_radius,border_width_unchecked,border_width_checked,fg_color,border_color,hover_color,text_color,text_color_disabled,text,textvariable,font,hover,state,command,variable,value)
ここで各引数の意味は下記のとおりです。(一部機械翻訳のため、変な日本語になってますが、ご承知おきお願いします。)
前回作成したチュートリアルのコードを改修して、ラジオボタンを追加しました。
ここでは給油、整備の選択のラジオボタンを追加してます。
# ライブラリのインポート箇所
# ----------------------------------------------------------------------------------
import customtkinter
import datetime
# ----------------------------------------------------------------------------------
# global 変数の定義箇所
# ----------------------------------------------------------------------------------
defoult_maintenance_refuel_radio = 1 # 給油/整備のどちらをデフォルトとするか(0:None、1:給油、2:整備)
defoult_model_state_radio = 1 # 車種1/車種2のどちらをデフォルトとするか(0:None、1:車種1、2:車種2)
model1 = "FIT(GK5)"
model2 = "VTR"
date_label = "日付を入力してください"
meter_label = "Odo meterの値を入力してください"
date_temp = datetime.date.today() # 今日の日付を一次的に格納
today_date = str(date_temp.year)+"/"+str(date_temp.month)+"/"+str(date_temp.day) # 今日の日付をyyyy/mm/dd形式で表示
# ----------------------------------------------------------------------------------
class App(customtkinter.CTk):
def __init__(self, defoult_maintenance_refuel_radio):
super().__init__()
self.title("給油/整備アプリ")
self.geometry("250x180")
self.grid_columnconfigure(0, weight=1)
self.grid_rowconfigure(0, weight=1)
self.make_common_frame()
def make_common_frame(self):
self.rm_button_state = customtkinter.IntVar() # 給油、整備のradioボタンの選択状態を格納する変数
self.rm_button_state.set(defoult_maintenance_refuel_radio) # 給油、整備のradioボタンの選択状態を格納する変数
self.refuel_maintenance_radio_button = customtkinter.CTkRadioButton(self, value=1, variable=self.rm_button_state, text="給油") # 給油のラジオボタンの作成
self.refuel_maintenance_radio_button.grid(row=0, column=0, padx=10, pady=(10, 0), sticky="w")
self.refuel_maintenance_radio_button = customtkinter.CTkRadioButton(self, value=2, variable=self.rm_button_state, text="整備") # 整備のラジオボタンの作成
self.refuel_maintenance_radio_button.grid(row=0, column=1, padx=10, pady=(10, 0), sticky="w")
self.button = customtkinter.CTkButton(self, text="my button", command=self.button_callback)
self.button.grid(row=7, column=0, padx=10, pady=10, sticky="ew")
def button_callback(self):
print("button pressed")
app = App(defoult_maintenance_refuel_radio)
app.mainloop()
このソースコードの実行結果は下記の通りです。
整備と給油だと給油の方が入力回数が多いため、整備、給油ボタンのデフォルトのチェックを給油の方にしました。デフォルトのチェックを付ける場合は下記のように".set"を使ってセットします。
self.rm_button_state.set(defoult_maintenance_refuel_radio) # 給油、整備のradioボタンの選択状態を格納する変数
詳細はソースコードを参照お願いします。
入力フォームの実装
続いて入力フォームを作成します。今回の場合は車種を入れられる入力フォームを作成していきます。入力フォームは下記のように実装できます。
customtkinter.CTkEntry(master, textvariable, width, height, corner_radius, fg_color, text_color, placeholder_text_color, placeholder_text, font, state)
各引数の意味は下記のとおりです。(こちらも一部機械翻訳なので、変な訳は無視してください)
入力フォームを追加したコードは下記のとおりです。(見栄えはまだ悪いですが、後ほど整えていきます。また、他にチェックボックスを追加してます。)
# ライブラリのインポート箇所
# ----------------------------------------------------------------------------------
import customtkinter
import datetime
# ----------------------------------------------------------------------------------
# global 変数の定義箇所
# ----------------------------------------------------------------------------------
defoult_maintenance_refuel_radio = 1 # 給油/整備のどちらをデフォルトとするか(0:None、1:給油、2:整備)
defoult_model_state_radio = 1 # 車種1/車種2のどちらをデフォルトとするか(0:None、1:車種1、2:車種2)
model1 = "FIT(GK5)"
model2 = "VTR"
date_label = "日付を入力してください"
meter_label = "Odo meterの値を入力してください"
date_temp = datetime.date.today() # 今日の日付を一次的に格納
today_date = str(date_temp.year)+"/"+str(date_temp.month)+"/"+str(date_temp.day) # 今日の日付をyyyy/mm/dd形式で表示
# ----------------------------------------------------------------------------------
class App(customtkinter.CTk):
def __init__(self, defoult_maintenance_refuel_radio):
super().__init__()
self.title("給油/整備アプリ")
self.geometry("500x200")
self.grid_columnconfigure(0, weight=1)
self.grid_rowconfigure(0, weight=1)
self.make_common_frame()
def make_common_frame(self):
self.rm_button_state = customtkinter.IntVar() # 給油、整備のradioボタンの選択状態を格納する変数
self.model_button_state = customtkinter.IntVar() # 車種1、車種2のradioボタンの選択状態を格納する変数
self.rm_button_state.set(defoult_maintenance_refuel_radio) # 給油、整備のradioボタンの選択状態を格納する変数
self.model_button_state.set(defoult_maintenance_refuel_radio) # 給油、整備のradioボタンの選択状態を格納する変数
self.refuel_maintenance_radio_button = customtkinter.CTkRadioButton(self, value=1, variable=self.rm_button_state, text="給油") # 給油のラジオボタンの作成
self.refuel_maintenance_radio_button.grid(row=0, column=0, padx=10, pady=(10, 0), sticky="w")
self.refuel_maintenance_radio_button = customtkinter.CTkRadioButton(self, value=2, variable=self.rm_button_state, text="整備") # 整備のラジオボタンの作成
self.refuel_maintenance_radio_button.grid(row=0, column=1, padx=10, pady=(10, 0), sticky="w")
self.model_radio_button = customtkinter.CTkRadioButton(self, value=1, variable=self.model_button_state, text="車種1") # 車種1のラジオボタンの作成
self.model_radio_button.grid(row=1, column=0, padx=10, pady=(10, 0), sticky="w")
self.model_radio_button = customtkinter.CTkRadioButton(self, value=2, variable=self.model_button_state, text="車種2") # 車種2のラジオボタンの作成
self.model_radio_button.grid(row=1, column=1, padx=10, pady=(10, 0), sticky="w")
self.model1_text_box = customtkinter.CTkEntry(self, placeholder_text="車種1を入力してください") # 車種1の入力欄の作成
self.model1_text_box.grid(row=2, column=0, padx=10, pady=(10, 0), sticky="w")
self.model1_text_box.insert(0, model1)
self.model2_text_box = customtkinter.CTkEntry(self, placeholder_text="車種2を入力してください") # 車種2の入力欄の作成
self.model2_text_box.grid(row=2, column=1, padx=10, pady=(10, 0), sticky="w")
self.model2_text_box.insert(0, model2)
self.date_label = customtkinter.CTkLabel(self, text = date_label) # 日付を入力してくださいというラベル
self.date_label.grid(row=3, column=0, padx=10, pady=(10, 0), sticky="w")
self.date_text_box = customtkinter.CTkEntry(self, placeholder_text=date_label) # 日付の入力欄
self.date_text_box.grid(row=4, column=0, padx=10, pady=(10, 0), sticky="w")
self.date_text_box.insert(0, today_date)
self.odo_meter_label = customtkinter.CTkLabel(self, text=meter_label) # odo meterの値を入力してくださいというラベル
self.odo_meter_label.grid(row=3, column=1, padx=10, pady=(10, 0), sticky="w")
self.odo_text_box = customtkinter.CTkEntry(self, placeholder_text=meter_label, width=200) # 日付の入力欄
self.odo_text_box.grid(row=4, column=1, padx=10, pady=(10, 0), sticky="w")
self.button = customtkinter.CTkButton(self, text="my button", command=self.button_callback)
self.button.grid(row=7, column=0, padx=10, pady=10, sticky="ew")
def button_callback(self):
print("button pressed")
app = App(defoult_maintenance_refuel_radio)
app.mainloop()
このソースコードの実行結果は下記のとおりです。
今回は車種のデフォルト値として現在乗っているバイクと車の名前を入れるようにしました。入力フォームにデフォルトで値を入れる場合は"入力フォーム名.insert(何文字目に入れるか、挿入する文字列)"で追加することが出来ます。
例えば今回のサンプルコードだと下記の部分です。
self.model1_text_box.insert(0, model1)
この例では0文字目に別で定義した変数model1の内容を表示するようにしています。
複数行を入力できる入力フォームを作成する
先ほどのエントリーフォームは1行入力することを目的としたものでした。備考欄などを作成する場合1行で収まらないことが考えられるため、複数行入力できる入力フォームを作成していきます。複数行入力したい場合は下記のように実装できます。
customtkinter.CTkTextbox(master, width, height, corner_radius, border_width, border_spacing, fg_color, border_color, text_color, scrollbar_button_color, scrollbar_button_hover_color, font, activate_scrollbars, state, wrap)
各引数の意味は下記のとおりです。(例のごとく機械翻訳です。)
複数入力できる備考欄も追加したコードは下記のとおりです。
# ライブラリのインポート箇所
# ----------------------------------------------------------------------------------
import customtkinter
import datetime
# ----------------------------------------------------------------------------------
# global 変数の定義箇所
# ----------------------------------------------------------------------------------
defoult_maintenance_refuel_radio = 1 # 給油/整備のどちらをデフォルトとするか(0:None、1:給油、2:整備)
defoult_model_state_radio = 1 # 車種1/車種2のどちらをデフォルトとするか(0:None、1:車種1、2:車種2)
model1 = "FIT(GK5)"
model2 = "VTR"
date_label = "日付を入力してください"
meter_label = "Odo meterの値を入力してください"
date_temp = datetime.date.today() # 今日の日付を一次的に格納
today_date = str(date_temp.year)+"/"+str(date_temp.month)+"/"+str(date_temp.day) # 今日の日付をyyyy/mm/dd形式で表示
# ----------------------------------------------------------------------------------
class App(customtkinter.CTk):
def __init__(self, defoult_maintenance_refuel_radio):
super().__init__()
self.title("給油/整備アプリ")
self.geometry("500x580")
self.grid_columnconfigure(0, weight=1)
self.grid_rowconfigure(0, weight=1)
self.make_common_frame()
def make_common_frame(self):
self.rm_button_state = customtkinter.IntVar() # 給油、整備のradioボタンの選択状態を格納する変数
self.model_button_state = customtkinter.IntVar() # 車種1、車種2のradioボタンの選択状態を格納する変数
self.rm_button_state.set(defoult_maintenance_refuel_radio) # 給油、整備のradioボタンの選択状態を格納する変数
self.model_button_state.set(defoult_maintenance_refuel_radio) # 給油、整備のradioボタンの選択状態を格納する変数
self.refuel_maintenance_radio_button = customtkinter.CTkRadioButton(self, value=1, variable=self.rm_button_state, text="給油") # 給油のラジオボタンの作成
self.refuel_maintenance_radio_button.grid(row=0, column=0, padx=10, pady=(10, 0), sticky="w")
self.refuel_maintenance_radio_button = customtkinter.CTkRadioButton(self, value=2, variable=self.rm_button_state, text="整備") # 整備のラジオボタンの作成
self.refuel_maintenance_radio_button.grid(row=0, column=1, padx=10, pady=(10, 0), sticky="w")
self.model_radio_button = customtkinter.CTkRadioButton(self, value=1, variable=self.model_button_state, text="車種1") # 車種1のラジオボタンの作成
self.model_radio_button.grid(row=1, column=0, padx=10, pady=(10, 0), sticky="w")
self.model_radio_button = customtkinter.CTkRadioButton(self, value=2, variable=self.model_button_state, text="車種2") # 車種2のラジオボタンの作成
self.model_radio_button.grid(row=1, column=1, padx=10, pady=(10, 0), sticky="w")
self.model1_text_box = customtkinter.CTkEntry(self, placeholder_text="車種1を入力してください") # 車種1の入力欄の作成
self.model1_text_box.grid(row=2, column=0, padx=10, pady=(10, 0), sticky="w")
self.model1_text_box.insert(0, model1)
self.model2_text_box = customtkinter.CTkEntry(self, placeholder_text="車種2を入力してください") # 車種2の入力欄の作成
self.model2_text_box.grid(row=2, column=1, padx=10, pady=(10, 0), sticky="w")
self.model2_text_box.insert(0, model2)
self.date_label = customtkinter.CTkLabel(self, text = date_label) # 日付を入力してくださいというラベル
self.date_label.grid(row=3, column=0, padx=10, pady=(10, 0), sticky="w")
self.date_text_box = customtkinter.CTkEntry(self, placeholder_text=date_label) # 日付の入力欄
self.date_text_box.grid(row=4, column=0, padx=10, pady=(10, 0), sticky="w")
self.date_text_box.insert(0, today_date)
self.odo_meter_label = customtkinter.CTkLabel(self, text=meter_label) # odo meterの値を入力してくださいというラベル
self.odo_meter_label.grid(row=3, column=1, padx=10, pady=(10, 0), sticky="w")
self.odo_text_box = customtkinter.CTkEntry(self, placeholder_text=meter_label, width=200) # 日付の入力欄
self.odo_text_box.grid(row=4, column=1, padx=10, pady=(10, 0), sticky="w")
self.remarks_label = customtkinter.CTkLabel(self, text="備考欄") # 備考欄というラベル
self.remarks_label.grid(row=5, column=0, padx=10, pady=(10, 0), sticky="w")
self.remarks_text_box = customtkinter.CTkTextbox(self, width=400) # 備考欄の入力
self.remarks_text_box.grid(row=6, column=0, padx=10, pady=(10, 0), sticky="w", columnspan=2)# 備考欄の入力(入力欄は列を結合)
self.button = customtkinter.CTkButton(self, text="my button", command=self.button_callback)
self.button.grid(row=7, column=0, padx=10, pady=10, sticky="ew")
def button_callback(self):
print("button pressed")
app = App(defoult_maintenance_refuel_radio)
app.mainloop()
実行結果は以下の通りです。備考欄に複数行入力をすることが出来るようになりました。
この記事の最後になりますが、フレームを追加して項目のグルーピングをしていきます。
フレームの作成の仕方についてですが、下記のように実装できます。
customtkinter.CTkFrame(master, width, height, border_width, fg_color, border_color)
各引数の意味は下記の通りです。(例のごとく機械翻訳です。)
各項目ごとにフレームを作成してグルーピングしたソースコードは下記の通りです。
# ライブラリのインポート箇所
# ----------------------------------------------------------------------------------
import customtkinter
import datetime
# ----------------------------------------------------------------------------------
# global 変数の定義箇所
# ----------------------------------------------------------------------------------
defoult_maintenance_refuel_radio = 1 # 給油/整備のどちらをデフォルトとするか(0:None、1:給油、2:整備)
defoult_model_state_radio = 1 # 車種1/車種2のどちらをデフォルトとするか(0:None、1:車種1、2:車種2)
model1 = "FIT(GK5)"
model2 = "VTR"
date_label = "日付を入力してください"
meter_label = "Odo meterの値を入力してください"
date_temp = datetime.date.today() # 今日の日付を一次的に格納
today_date = str(date_temp.year)+"/"+str(date_temp.month)+"/"+str(date_temp.day) # 今日の日付をyyyy/mm/dd形式で表示
common_bg_color = "#7BB6E3"
common_item_color = "#DCDCDC"
# ----------------------------------------------------------------------------------
class App(customtkinter.CTk):
def __init__(self, defoult_maintenance_refuel_radio):
super().__init__()
self.title("給油/整備アプリ")
self.geometry("500x580")
self.grid_columnconfigure(0, weight=1)
self.grid_rowconfigure(0, weight=1)
self.make_common_frame()
def make_common_frame(self):
self.common_frame = customtkinter.CTkFrame(self, fg_color=common_bg_color) # 共通項目のフレーム作成
self.common_frame.grid(row=0, column=0, padx=10, pady=5, sticky="nsw")
self.common_label_frame = customtkinter.CTkFrame(self.common_frame,fg_color=common_item_color) # 共通項目のラベルを書くフレーム作成
self.common_label_frame.grid(row=0, column=0, padx=10, pady=5, sticky="nsw",)
self.rm_frame = customtkinter.CTkFrame(self.common_frame,fg_color=common_item_color) # 給油のフレーム作成
self.rm_frame.grid(row=1, column=0, padx=10, pady=5, sticky="nsw")
self.model_frame = customtkinter.CTkFrame(self.common_frame,fg_color=common_item_color) # 車種のフレーム作成
self.model_frame.grid(row=2, column=0, padx=10, pady=5, sticky="nsw")
self.dateodo_frame = customtkinter.CTkFrame(self.common_frame,fg_color=common_item_color) # 日付とodoのフレーム作成
self.dateodo_frame.grid(row=3, column=0, padx=10, pady=5, sticky="nsw")
self.remark_frame = customtkinter.CTkFrame(self.common_frame,fg_color=common_item_color) # 備考欄のフレーム作成
self.remark_frame.grid(row=4, column=0, padx=10, pady=5, sticky="nsw")
self.rm_button_state = customtkinter.IntVar() # 給油、整備のradioボタンの選択状態を格納する変数
self.model_button_state = customtkinter.IntVar() # 車種1、車種2のradioボタンの選択状態を格納する変数
self.rm_button_state.set(defoult_maintenance_refuel_radio) # 給油、整備のradioボタンの選択状態を格納する変数
self.model_button_state.set(defoult_maintenance_refuel_radio) # 給油、整備のradioボタンの選択状態を格納する変数
self.date_label = customtkinter.CTkLabel(self.common_label_frame, text="共通項目", bg_color=common_item_color, corner_radius=1000) # 共通項目のラベル
self.date_label.grid(row=0, column=0, padx=0, pady=0, sticky="w")
self.refuel_maintenance_radio_button = customtkinter.CTkRadioButton(self.rm_frame, value=1, variable=self.rm_button_state, text="給油", width=200) # 給油のラジオボタンの作成
self.refuel_maintenance_radio_button.grid(row=1, column=0, padx=10, pady=10, sticky="e")
self.refuel_maintenance_radio_button = customtkinter.CTkRadioButton(self.rm_frame, value=2, variable=self.rm_button_state, text="整備",width=200) # 整備のラジオボタンの作成
self.refuel_maintenance_radio_button.grid(row=1, column=1, padx=10, pady=10, sticky="ew")
self.model_radio_button = customtkinter.CTkRadioButton(self.model_frame, value=1, variable=self.model_button_state, text="車種1") # 車種1のラジオボタンの作成
self.model_radio_button.grid(row=2, column=0, padx=10, pady=3, sticky="ew")
self.model_radio_button = customtkinter.CTkRadioButton(self.model_frame, value=2, variable=self.model_button_state, text="車種2") # 車種2のラジオボタンの作成
self.model_radio_button.grid(row=2, column=1, padx=10, pady=3, sticky="ew")
self.model1_text_box = customtkinter.CTkEntry(self.model_frame, placeholder_text="車種1を入力してください", width=200) # 車種1の入力欄の作成
self.model1_text_box.grid(row=3, column=0, padx=10, pady=3, sticky="ew")
self.model1_text_box.insert(0, model1)
self.model2_text_box = customtkinter.CTkEntry(self.model_frame, placeholder_text="車種2を入力してください", width=200) # 車種2の入力欄の作成
self.model2_text_box.grid(row=3, column=1, padx=10, pady=3, sticky="ew")
self.model2_text_box.insert(0, model2)
self.date_label = customtkinter.CTkLabel(self.dateodo_frame, text = date_label) # 日付を入力してくださいというラベル
self.date_label.grid(row=4, column=0, padx=10, pady=0, sticky="w")
self.date_text_box = customtkinter.CTkEntry(self.dateodo_frame, placeholder_text=date_label, width=200) # 日付の入力欄
self.date_text_box.grid(row=5, column=0, padx=10, pady=3, sticky="ew")
self.date_text_box.insert(0, today_date)
self.odo_meter_label = customtkinter.CTkLabel(self.dateodo_frame, text=meter_label) # odo meterの値を入力してくださいというラベル
self.odo_meter_label.grid(row=4, column=1, padx=10, pady=0, sticky="w")
self.odo_text_box = customtkinter.CTkEntry(self.dateodo_frame, placeholder_text=meter_label, width=200) # odoの入力欄
self.odo_text_box.grid(row=5, column=1, padx=10, pady=3, sticky="ew")
self.remarks_label = customtkinter.CTkLabel(self.remark_frame, text="備考欄") # 備考欄というラベル
self.remarks_label.grid(row=6, column=0, padx=10, pady=0, sticky="w")
self.remarks_text_box = customtkinter.CTkTextbox(self.remark_frame, width=420) # 備考欄の入力
self.remarks_text_box.grid(row=7, column=0, padx=10, pady=5, sticky="ew", columnspan=2)# 備考欄の入力(入力欄は列を結合)
self.button = customtkinter.CTkButton(self, text="my button", command=self.button_callback)
self.button.grid(row=8, column=0, padx=10, pady=10, sticky="ew")
def button_callback(self):
print("button pressed")
app = App(defoult_maintenance_refuel_radio)
app.mainloop()
Tkinterの場合はラベルフレームというものがあり、フレームにラベルと枠線を簡単につけられたのですが、CustomTkinterの場合はラベルフレームはなさそうです。。。(Tkinterのフレームラベルについてはこちら参照お願いします。)
一応GitHubでは他の人が要望を出していたため、もしかしたら今後追加されるかもしれないです。(GitHubのリンクはこちら)
CustomTkinterではラベルフレームが無いため、ラベルを組み合わせて項目名を作成してます。実行結果は下記のとおりです。
まとめ
今回は共通項目という欄のGUIを作成しました。ラジオボタンや入力フォームなどの基本的な項目の作り方は理解できたため、これを活かして他の項目も作っていきます。
また、ボタンを押した際の動作について次回以降追加していきます。
0 件のコメント:
コメントを投稿