Elsaの技術日記(徒然なるままに)

主に自分で作ったアプリとかの報告・日記を記載

MENU

初めてのtkinter (併せてpythonでsql実行) ~part2~

前回はGUI上で項目を入力するとDBに入力項目を保存(登録)するところまで作成いたしました。
elsammit-beginnerblg.hatenablog.com



今回は、登録内容を表にして表示するところについて作成したので記載していきたいと思います。
f:id:Elsammit:20200530194025j:plain

作成した画面はこちらになります。
結果ボタンを押下すると別画面が表示され、別画面にて登録結果が表形式で表示するように作成いたしました。
f:id:Elsammit:20200620171118p:plain

追加内容を大きく分けると、、、
 ・別画面の追加と表示
 ・表形式のモジュール用意
 ・DBから登録内容読み出しと表への表示
となります。



【目次】

別画面の追加と表示

まず別画面の追加作成するコードはこちらになります。
前回作成したメイン画面の生成とほとんど同じですね。
違うのはTkとToplevelぐらいです。

newWindow = tkinter.Toplevel(root)
newWindow.title("タイトル名")
newWindow.geometry("260x350")

TkとToplebelの違いですがこちらに書かれておりました。
Tkはメイン画面(root)のみですが、Toplevelは子ウィンドウとしていくつも生成できるようです。
tkinter - TkとToplevelの違い | tkinter Tutorial


さらにボタン押下イベントで上記コードがコールされるようにすれば、追加画面をボタン押下で表示させることができます。

表形式のモジュール用意

表形式で表示するにあたって、Treeviewを利用しました。
Treeviewを用いるにあたり、tkinter.ttkをインポートする必要があります。
Treeviewの使い方ですが、百聞は一見にしかず。まずはコードを載せます。

#ウィンドウにTreeviewを登録
tree = ttk.Treeview(newWindow)

#列数を定義
tree["columns"] = (1,2,3)
tree["show"] = "headings"

#各列ごとの幅(大きさ)設定
tree.column(1,width=75)
tree.column(2,width=100)
tree.column(3,width=75)

#表示する列名定義
tree.heading(1,text="日付")
tree.heading(2,text="アイテム")
tree.heading(3,text="金額")

#行(データ)を追加
tree.insert("","end",values=("2020/6/1","items","123"))

流れとしては、
 ・ウィンドウにTreeviewを登録
 ・列数を定義(今回は1~3の3つ)
 ・各列ごとの幅(大きさ)設定
 ・表示する列名定義
 ・行(データ)を追加
となります。

DBから登録内容読み出しと表への表示

まずテーブルからのデータ読み出しです。
pythonでselect * fromで複数データを読み出せばよいので、、、

try:
    conn = sqlite3.connect('database.db')
    c = conn.cursor()
    list_buf = []
    for buf in c.execute("select * from kakeibo"):
        list_buf.append(buf)
    conn.close()
except sqlite3.Error as e:
    print(e)

select * fromの結果が1行ずつ取得できる仕様であったため、
for文を用いて、1行ずつlist型で定義した変数に追加しています。

そして取得したデータをtreeviewに追加していけばよいので、、、

    for buf in list_buf :
        tree.insert("","end",values=buf)

最後に

前回よりもthinkerに慣れたのか、あまり時間かからずに作り上げることができました!!
慣れって重要ですね!!
だけど、thinkerもGUI上でポチポチ操作すれば画面設計できるようにすることはできないのだろうか?。。。
今回レベルならそこまで問題にならないけど、規模が大きくなるとやはり座標指定とかウィンドウサイズ指定とか大変になるから楽出来たらな。。。

参考としてソースコード全体を載せておきました。

参考(ソースコード)

# -*- coding: utf8 -*-

import sys
import tkinter
import tkinter.ttk as ttk
import sqlite3
import datetime

root = tkinter.Tk()
root.title("家計簿")
root.geometry("260x100")

#新規ウィンドウ登録.
def ViewNewWindow(self):
    newWindow = tkinter.Toplevel(root)
    newWindow.title("結果表示")
    newWindow.geometry("260x350")
    Make_ResultMap(self,newWindow)

#DBからの読み出し結果をTreeviewで表示
def Make_ResultMap(self,newWindow):
    #ウィンドウにTreeviewを登録
    tree = ttk.Treeview(newWindow)

    #列数を定義
    tree["columns"] = (1,2,3)
    tree["show"] = "headings"

    #各列ごとの幅(大きさ)設定
    tree.column(1,width=75)
    tree.column(2,width=100)
    tree.column(3,width=75)

    #表示する列名定義
    tree.heading(1,text="日付")
    tree.heading(2,text="アイテム")
    tree.heading(3,text="金額")
    
    #DBから登録データ読み出し.
    Getlist = Get_sql()
    
    #treeviewに追加.
    for buf in Getlist:
        tree.insert("","end",values=buf)

    tree.pack()

#テキストボックスからの入力データ読み出し
def GetValues(self):
    value_item = Input_item.get()
    value_money = Input_money.get()

    #DBへのデータ登録.
    Insert_sql(value_item,value_money)

#DBからデータ取得.
def Get_sql():
    try:
        conn = sqlite3.connect('database.db')
        c = conn.cursor()
        list_buf = []
        for buf in c.execute("select * from kakeibo"):
            list_buf.append(buf)
        conn.close()
    except sqlite3.Error as e:
        print(e)
    
    print(list_buf)
    return list_buf

#DBへ入力データ挿入.
def Insert_sql(item,money):
    now = datetime.datetime.now()
    
    try:
        conn = sqlite3.connect('database.db')
        c = conn.cursor()
        c.execute("insert into kakeibo values (?,?,?)",(now.strftime('%Y/%m/%d'),str(item),money))
        conn.commit()
        conn.close()
    except sqlite3.Error as e:
        print(e)

#main画面生成.
item = tkinter.Label(text=u'物品')
Input_item = tkinter.Entry(width=30)
Input_item.insert(tkinter.END,"文字列を入力してください")

money = tkinter.Label(text=u'金額')
Input_money = tkinter.Entry(width=30)
Input_money .insert(tkinter.END,"金額を入力してください")

#テキストボックス生成.
item.grid(row=0)
Input_item.grid(row=0,column=1)
money.grid(row=1)
Input_money.grid(row=1,column=1)

#ボタン生成
Button = tkinter.Button(root,text=u'ボタン')
Button.bind("<Button-1>",GetValues) #ボタンイベント登録.
Button.grid(row=2)

#ボタン生成
Button = tkinter.Button(root,text=u'結果表示')
Button.bind("<Button-1>",ViewNewWindow) #ボタンイベント登録.
Button.grid(row=3)

root.mainloop()