⑪ コールバック関数の定義【python tkinter sqlite3で家計簿を作る】
⑪ コールバック関数の定義【python tkinter sqlite3で家計簿を作る】
今回は、「表示」ボタンが押下されたときのコールバック関数の定義をする。
この処理は、期間に入力された日付に応じてレコードを絞り込むものである。
前回までに作成したGUI
コールバック関数に必要な処理は
- Treeviewのアイテム(item)を全て削除する
- 期間に入力された値をSELECT文のWHERE句に組み込む
- 再度、Treeviewのアイテムを表示
となる。
Treeviewのアイテムを全て削除する
Treeviewのitemを全て削除するには、deleteメソッドを用いる。
deleteメソッドには、削除するアイテムを指定しなければならない。
この指定には、itemを指定しなければならない。
全てのitemを取得するには、tree.get_childern()を用いる。
tree.get_childern()はリストの値で返ってくるため、for文で全てのitemを削除する。
for i in tree.get_children() tree.delete(i)
また、結合(starred expression)の機能を用いて、シンプルに記述することができる。
tree.delete(*tree.get_children())
期間に入力された値をSELECT文のWHERE句に組み込む
SELECT文のWHERE句にBETWEEN演算子を用いて、開始日と終了日を指定する。
sql = """ SELECT acc_date,item_name,amount FROM acc_data as a,item as i WHERE a.item_code = i.item_code AND acc_date BETWEEN '{}' AND '{}' ORDER BY acc_date """.format(start,end)
ただし、開始日と終了日が空欄だった場合エラーになるので、デフォルト値を指定する必要がある。
if start == "": start = "1900/01/01" if end == "": end = "2100/01/01" sql = """ SELECT acc_date,item_name,amount FROM acc_data as a,item as i WHERE a.item_code = i.item_code AND acc_date BETWEEN '{}' AND '{}' ORDER BY acc_date """.format(start,end)
最後にこのSQLを発行して、Treeviewのアイテムに追加すればよい。
このコールバック関数をまとめると次のようになる。
# 表示ボタンが押されたときの処理 def select_sql(start,end): # treeviewのアイテムをすべて削除 tree.delete(*tree.get_children()) # 開始日と終了日が空欄だったらデフォルト値の設定 if start == "": start = "1900/01/01" if end == "": end = "2100/01/01" #SELECT文の作成 sql = """ SELECT acc_date,item_name,amount FROM acc_data as a,item as i WHERE a.item_code = i.item_code AND acc_date BETWEEN '{}' AND '{}' ORDER BY acc_date """.format(start,end) # ツリービューにアイテムの追加 i=0 for r in c.execute(sql): # 金額(r[2])を通貨形式に変換 r = (r[0],r[1],"¥{:,d}".format(r[2])) tree.insert("","end",tags=i,values=r) if i & 1: tree.tag_configure(i,background="#CCFFFF") i+=1
処理をテストする。
それぞれ、期間を入力して、その期間に応じたレコードを表示させることができた!
以上のコールバック関数を組み込んだ表示画面GUIのスクリプトは次のようになる。
# -*- coding: utf-8 -*- import tkinter as tk import tkinter.ttk as ttk import sqlite3 # 表示ボタンが押されたときの処理 def select_sql(start,end): # treeviewのアイテムをすべて削除 tree.delete(*tree.get_children()) # 開始日と終了日が空欄だったらデフォルト値の設定 if start == "": start = "1900/01/01" if end == "": end = "2100/01/01" #SELECT文の作成 sql = """ SELECT acc_date,item_name,amount FROM acc_data as a,item as i WHERE a.item_code = i.item_code AND acc_date BETWEEN '{}' AND '{}' ORDER BY acc_date """.format(start,end) # ツリービューにアイテムの追加 i=0 for r in c.execute(sql): # 金額(r[2])を通貨形式に変換 r = (r[0],r[1],"¥{:,d}".format(r[2])) tree.insert("","end",tags=i,values=r) if i & 1: tree.tag_configure(i,background="#CCFFFF") i+=1 # 空のデータベースを作成して接続する dbname = "database.db" c = sqlite3.connect(dbname) c.execute("PRAGMA foreign_keys = 1") # rootフレームの設定 root = tk.Tk() root.title("家計簿アプリ") root.geometry("400x500") # メニューの設定 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=15) frame1.pack() label2 = tk.Label(frame1,font=("",14),text="期間 ") label2.pack(side="left") entry1 = tk.Entry(frame1,font=("",14),justify="center",width=12) entry1.pack(side="left") label3 = tk.Label(frame1,font=("",14),text=" ~ ") label3.pack(side="left") entry2 = tk.Entry(frame1,font=("",14),justify="center",width=12) entry2.pack(side="left") # 表示ボタンの設定 button4 = tk.Button(root,text="表示", font=("",16), width=10,bg="gray", command=lambda:select_sql(entry1.get(),entry2.get())) button4.pack() # ツリービューの作成 tree = ttk.Treeview(root,padding=10) tree["columns"] = (1,2,3) tree["show"] = "headings" tree.column(1,width=100) tree.column(2,width=75) tree.column(3,width=100) tree.heading(1,text="日付") tree.heading(2,text="内訳") tree.heading(3,text="金額") # ツリービューのスタイル変更 style = ttk.Style() # TreeViewの全部に対して、フォントサイズの変更 style.configure("Treeview",font=("",12)) # TreeViewのHeading部分に対して、フォントサイズの変更と太字の設定 style.configure("Treeview.Heading",font=("",14,"bold")) # SELECT文の作成 sql = """ SELECT acc_date,item_name,amount FROM acc_data as a,item as i WHERE a.item_code = i.item_code ORDER BY acc_date """ # ツリービューにアイテムの追加 i=0 for r in c.execute(sql): # 金額(r[2])を通貨形式に変換 r = (r[0],r[1],"¥{:,d}".format(r[2])) tree.insert("","end",tags=i,values=r) if i & 1: tree.tag_configure(i,background="#CCFFFF") i+=1 # ツリービューの配置 tree.pack(fill="x",padx=20,pady=20) # メインループ root.mainloop()
今回はここまで!
いよいよ次回が最終回。最後に画面遷移の処理を定義する。
質問や記事の誤りがありましたらコメントお願いします。
2017/6/4追記:sqlite3は、日付型(date型)というデータ型がない。日付として例えばBETWEEN演算子などの処理を認識させるためには、
'YYYY-MM-DD'
'YYYY-MM-DD hh:mm:ss'
の形式で記述しなければならない。
入力形式にYYYY/MM/DDと入力されていたら、replaceメソッドで'/'を'-'に置き換える処理が必要になる。
前の記事
⑩ 複数のウィジェットを配置【python tkinter sqlite3で家計簿を作る】
次の記事
⑫ 画面遷移の処理を定義(最終回)【python tkinter sqlite3で家計簿を作る】