⑦ GUIの実装 sqlite3への登録【python tkinter sqlite3で家計簿を作る】
⑦ GUIの実装 sqlite3への登録【python tkinter sqlite3で家計簿を作る】
今回から遂に、GUIの実装(クリックしたときの処理を定義)を行う。
最終的には、入力画面に各項目を入力し、「登録」を押下するとsqlite3のDBに登録(SQLを発行)するという処理を実装する。
前回までに作成したGUI
Buttonウィジェットのクリック時の処理を定義する
import tkinter as tk # ボタンがクリックされた時の処理をコールバック関数として定義 def callback(): print("Hello World") root = tk.Tk() # ボタンを作成(rootに配置、テキストの指定、ボタンがクリックされた時に呼び出す関数(コールバック関数)を指定) button = tk.Button(root,text="OK",command=callback) button.pack() root.mainloop()
OKボタンをクリックすると、インタプリタコンソールにHello Worldの文字が表示されたことがわかる。
引数があるコールバック関数を定義する場合
Buttonのcommandのコールバック関数に引数を用いる場合はラムダ形式で記述しなければならない。
import tkinter as tk # 引数があるコールバック関数を定義 def callback(name): print("Hello World " + name) root = tk.Tk() # ボタンを作成(commandをラムダ形式で記述) button = tk.Button(root,text="OK",command=lambda:callback("memopy")) button.pack() root.mainloop()
Entryウィジェットのテキストを読み取る
Entryウィジェットに入力されたテキストを読み取るためには、getメソッドを使う。
import tkinter as tk # GETボタンが押された時のコールバック関数 def text_get(): # Entryウィジェットのテキストを読み取るgetメソッド text = entry.get() print(text) root = tk.Tk() # Entryウィジェットの作成 entry = tk.Entry(root,width=10) entry.pack() # Buttonウィジェットの作成 button = tk.Button(root,text="GET",command=text_get) button.pack()
Entry内のテキストを読み取り、インタプリタコンソールに出力した。
以上の機能を用いて、「登録」をクリックすると、Entry内のテキストを読み取ったSQL文を作成してみる。
※本来は内訳に「食費」と入力されていたら、外部テーブル(itemテーブル)を参照して該当するitem_codeに置き換える処理が必要だが、今は、直接item_codeの値を内訳Entryに入力することにする。
# -*- coding: utf-8 -*- import tkinter as tk def create_sql(): # 日付を読み取る acc_data = entry1.get() # 内訳を読み取る item_code = entry2.get() # 金額を読み取る amount = entry3.get() # SQLを作成して出力する print(""" INSERT INTO acc_data(acc_date,item_code,amount) VALUES('{}',{},{}); """.format(acc_data,item_code,amount)) # rootフレームの設定 root = tk.Tk() root.title("家計簿アプリ") root.geometry("300x280") # メニューの設定 frame = tk.Frame(root,bd=2,relief="ridge") frame.pack(fill="x") button1 = tk.Button(frame,text="入力") button1.pack(side="left") button2 = tk.Button(frame,text="表示") button2.pack(side="left") button3 = tk.Button(frame,text="終了") button3.pack(side="right") # 入力画面ラベルの設定 label1 = tk.Label(root,text="【入力画面】",font=("",16),height=2) label1.pack(fill="x") # 日付のラベルとエントリーの設定 frame1 = tk.Frame(root,pady=10) frame1.pack() label2 = tk.Label(frame1,font=("",14),text="日付") label2.pack(side="left") entry1 = tk.Entry(frame1,font=("",14),justify="center",width=15) entry1.pack(side="left") # 内訳のラベルとエントリーの設定 frame2 = tk.Frame(root,pady=10) frame2.pack() label3 = tk.Label(frame2,font=("",14),text="内訳") label3.pack(side="left") entry2 = tk.Entry(frame2,font=("",14),justify="center",width=15) entry2.pack(side="left") # 金額のラベルとエントリーの設定 frame3 = tk.Frame(root,pady=10) frame3.pack() label4 = tk.Label(frame3,font=("",14),text="金額") label4.pack(side="left") entry3 = tk.Entry(frame3,font=("",14),justify="center",width=15) entry3.pack(side="left") # 登録ボタンの設定 button4 = tk.Button(root,text="登録",font=("",16),width=10,bg="gray",command=create_sql) button4.pack() # メインループ root.mainloop()
登録ボタンをクリックするとSQLが発行されてインタプリタコンソールに出力された!!
次にデータベースの実装【python tkinter sqlite3で家計簿を作る】 - memopyで定義したデータベースとGUIの処理を連結する。
# -*- coding: utf-8 -*- import tkinter as tk import sqlite3 # 空のデータベースを作成して接続する dbname = "database.db" c = sqlite3.connect(dbname) c.execute("PRAGMA foreign_keys = 1") # 既にデータベースが登録されている場合は、ddlの発行でエラーが出るのでexceptブロックで回避する try: # itemテーブルの定義 ddl = """ CREATE TABLE item ( item_code INTEGER PRIMARY KEY AUTOINCREMENT, item_name TEXT NOT NULL UNIQUE ); """ # SQLの発行 c.execute(ddl) # acc_dataテーブルの定義 ddl = """ CREATE TABLE acc_data ( id INTEGER PRIMARY KEY AUTOINCREMENT, acc_date DATE NOT NULL, item_code INTEGER NOT NULL, amount INTEGER, FOREIGN KEY(item_code) REFERENCES item(item_code) ); """ # itemテーブルへリファレンスデータの登録 c.execute(ddl) c.execute("INSERT INTO item(item_name) VALUES('食費');") c.execute("INSERT INTO item(item_name) VALUES('住宅費');") c.execute("INSERT INTO item(item_name) VALUES('光熱費');") c.execute("COMMIT;") except: pass # 登録ボタンがクリックされた時にデータをDBに登録するコールバック関数 def create_sql(): # 日付の読み取り acc_data = entry1.get() # 内訳の読み取り item_code = entry2.get() # 金額の読み取り amount = entry3.get() # SQLを発行してDBへ登録 try: c.execute(""" INSERT INTO acc_data(acc_date,item_code,amount) VALUES('{}',{},{}); """.format(acc_data,item_code,amount)) c.execute("COMMIT;") print("1件登録しました") # ドメインエラーなどにより登録できなかった場合のエラー処理 except: print("エラーにより登録できませんでした") # rootフレームの設定 root = tk.Tk() root.title("家計簿アプリ") root.geometry("300x280") # メニューの設定 frame = tk.Frame(root,bd=2,relief="ridge") frame.pack(fill="x") button1 = tk.Button(frame,text="入力") button1.pack(side="left") button2 = tk.Button(frame,text="表示") button2.pack(side="left") button3 = tk.Button(frame,text="終了") button3.pack(side="right") # 入力画面ラベルの設定 label1 = tk.Label(root,text="【入力画面】",font=("",16),height=2) label1.pack(fill="x") # 日付のラベルとエントリーの設定 frame1 = tk.Frame(root,pady=10) frame1.pack() label2 = tk.Label(frame1,font=("",14),text="日付") label2.pack(side="left") entry1 = tk.Entry(frame1,font=("",14),justify="center",width=15) entry1.pack(side="left") # 内訳のラベルとエントリーの設定 frame2 = tk.Frame(root,pady=10) frame2.pack() label3 = tk.Label(frame2,font=("",14),text="内訳") label3.pack(side="left") entry2 = tk.Entry(frame2,font=("",14),justify="center",width=15) entry2.pack(side="left") # 金額のラベルとエントリーの設定 frame3 = tk.Frame(root,pady=10) frame3.pack() label4 = tk.Label(frame3,font=("",14),text="金額") label4.pack(side="left") entry3 = tk.Entry(frame3,font=("",14),justify="center",width=15) entry3.pack(side="left") # 登録ボタンの設定 button4 = tk.Button(root,text="登録",font=("",16),width=10,bg="gray",command=create_sql) button4.pack() # メインループ root.mainloop()
3件登録した。
正しく登録されているか、インタプリタで確認してみる。
(インタプリタで確認するためには、GUIを終了し(右上の×ボタン)、mainloopを開放する必要がある。)
OK!!登録されていた!!
今日はここまで!
質問や記事の間違いがありましたらコメントお願いします。
2017/6/4追記:sqlite3は、日付型(date型)というデータ型がない。日付として例えばBETWEEN演算子などの処理を認識させるためには、
'YYYY-MM-DD'
'YYYY-MM-DD hh:mm:ss'
の形式で記述しなければならない。
入力形式にYYYY/MM/DDと入力されていたら、replaceメソッドで'/'を'-'に置き換える処理が必要になる。
前の記事
⑥ LabelとEntryの配置【python tkinter sqlite3で家計簿を作る】
次の記事
⑧ ドロップダウンリストの作成【python tkinter sqlite3で家計簿を作る】