python tkinter 色(color)の設定方法
python tkinter 色(color)の設定方法
python tkinterにおける色(color)の設定方法がいくつかあるので整理する。
参考ページ(英語):http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/colors.html
python クラスの定義と継承とは
python クラスの定義と継承とは
前回の記事は、tkinterのドキュメントのサンプルスクリプトとして記載されている"A Simple Hello World Program"が難しすぎる。という記事を投稿した。
前の記事
python tkinterのクラス化手法によるGUI作成 - memopy
今回は、pythonのクラスとはなにか。クラスの継承とはなにかについてまとめたいと思う。
特に、クラスの継承はpython2とpython3で方法が一部異なるため、この点を整理したい。
python tkinterのクラス化手法によるGUI作成
python tkinterのドキュメント"A Simple Hello World Program"が難しすぎる
皆さんはpython tkinterのドキュメントをご覧になったことがあるだろうか。
※python3の場合
25.1. tkinter — Python interface to Tcl/Tk — Python 3.6.1 documentation
※python2の場合
24.1. Tkinter — Python interface to Tcl/Tk — Python 2.7.13 documentation
A Simple Hello World Program
この中にA Simple Hello World Programというサンプルスクリプトがある。
しかし、このサンプルスクリプトはpython初心者にとって非常に難しい。
※python3の場合
import tkinter as tk class Application(tk.Frame): def __init__(self, master=None): super().__init__(master) self.pack() self.create_widgets() def create_widgets(self): self.hi_there = tk.Button(self) self.hi_there["text"] = "Hello World\n(click me)" self.hi_there["command"] = self.say_hi self.hi_there.pack(side="top") self.quit = tk.Button(self, text="QUIT", fg="red", command=root.destroy) self.quit.pack(side="bottom") def say_hi(self): print("hi there, everyone!") root = tk.Tk() app = Application(master=root) app.mainloop()
※python2の場合
from Tkinter import * class Application(Frame): def say_hi(self): print "hi there, everyone!" def createWidgets(self): self.QUIT = Button(self) self.QUIT["text"] = "QUIT" self.QUIT["fg"] = "red" self.QUIT["command"] = self.quit self.QUIT.pack({"side": "left"}) self.hi_there = Button(self) self.hi_there["text"] = "Hello", self.hi_there["command"] = self.say_hi self.hi_there.pack({"side": "left"}) def __init__(self, master=None): Frame.__init__(self, master) self.pack() self.createWidgets() root = Tk() app = Application(master=root) app.mainloop() root.destroy()
いずれにせよ、このスタンドアロンスクリプトを実行すると、次のGUIが作成され、ボタンをクリックすると、インタプリタコンソールにhi there, everyone!と、いかにも英語圏の挨拶が表示されるプログラムとなっている。
このサンプルスクリプトは、A Simple Hello World Programという位置付けでありながら、次の点で初心者にとっては非常に難しいものである。
また次のような遠因も輪をかけてこのA Simple Hello World Programを難しくしている。
- そもそも、tkinterの日本語ドキュメントや文献が少ない
- 文献によって、手続き型で記述しているものと、オブジェクト指向によって記述しているものがあり、両者を混在させて参考にできない
私もそうであったが、最初は、インターネットや書籍に公開されているスクリプトをコピーして、自分のパソコンで動かすであろう。
そして、そのあと、自分なりにいろいろ変更を加えてみて、GUIがどのように変化するのか学習するものである。
しかし、pythonはご存知のとおり、日本語のドキュメントが少ないし、さらにtkinterはもっと日本語ドキュメントが少ない。そして、python2系と3系では、クラス化の手法がかなり異なるため、文献によっては自分の環境では動作せず行き詰る。
私もこのtkinterは特に行き詰ったため、その点を整理したいと思う。
⑫ 画面遷移の処理を定義(最終回)【python tkinter sqlite3で家計簿を作る】
⑫ 画面遷移の処理を定義(最終回)【python tkinter sqlite3で家計簿を作る】
家計簿アプリもほとんど完成に近づいてきた。
今回は各画面の遷移の処理を実装する。
メインスクリプトに対して、2つの画面を表示する関数し、その関数の中にさらに各ボタンが押下されたときのコールバック関数を定義している。
関数の状況を概観すると次のスクリプトになる。
# -*- coding:utf-8 -*- def create_gui(): "登録画面を表示する関数" def select_button(): "表示ボタンが押下されたときに表示画面を表示する" pass def qui_button(): "終了ボタンが押下されたときにアプリを終了する" pass def qui_button(): "登録ボタンが押下されたときにデータをDBに登録する" pass # ここに登録画面のGUI部分の定義 pass def select_gui(): "表示画面を表示する関数" def create_button(): "登録ボタンが押下されたときに表示画面を表示する" pass def qui_button(): "終了ボタンが押下されたときにアプリを終了する" pass def select_button(): "表示ボタンが押下されたときに表にデータを表示する" pass # ここに表示画面のGUI部分の定義 pass # このスクリプトが実行されたときに最初に登録画面を表示する create_gui()
それぞれ、passと記載した箇所に、今までに作成したコードを転記していく。
⑪ コールバック関数の定義【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で家計簿を作る】