tkinterで表形式の入力画面をつくる方法

python

この記事に書いてあること

下図の左みたいな表形式の入力画面をつくるコードについて書いています。

これをpython tkinterで普通につくろうとすると行数が増えるにつれてコードが長くなる一方です。

そこで、comboboxやentryboxをlistの要素として扱い、for文で回して簡略化することにしました。

コード

import pandas as pd
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog

def Input():
    root = tk.Tk()
    root.title('Table Input')

    frame = ttk.Frame(root)
    frame.grid(row=0, column=0)
    
    # 項目をつくる
    items = ['項目1', '項目2', '項目3']
    for i in range(0, len(items)):
        label_item = ttk.Label(frame,
        text=items[i])
        label_item.grid(row=0, column=i)

    n = 5 # 行数
    # 項目1
    items1 = [0] * n
    for i in range(0, n): 
        items1[i] = ttk.Combobox(frame,
                                 state='readonly',
                                 width=10)
        items1[i]['values'] = ('A', 'B', 'C')
        items1[i].grid(row=i+1, column=0) 

    # 項目2
    items2 = [0] * n
    for i in range(0, n):
        items2[i] = ttk.Combobox(frame,
                                 state='readonly',
                                 width=10)
                                 items2[i]['values'] = ('a', 'b', 'c', 'd', 'e', 'f')
        items2[i].grid(row=i+1, column=1) 

    # 項目3
    items3 = [0] * n
    for i in range(0, n):
        items3[i] = tk.StringVar()
        item3 = ttk.Entry(frame,
                          textvariable=items3[i],
                          width=10)
        item3.grid(row=i+1,column=2)

    # 実行ボタン
    def execute():
        #これまでの入力をリストに入れる
        table_data = []
        for i in range(0, n):
            table_data.append([items1[i].get(), 
                               items2[i].get(), 
                               items3[i].get()]) 
        # pandas dataframeに変換
        df = pd.DataFrame(table_data, columns=['項目1', '項目2', '項目3'])

        # 結果表示
        Output(df)

    button = ttk.Button(root,
                        text='計算',
                        padding=5,
                        command=execute)
                        button.grid(row=1, column=0)
    root.mainloop()

def Output(df):
    root = tk.Tk()
    root.title('Table Output')

    frame = ttk.Frame(root, padding=5)
    frame.grid(row=0, column=0)

    # ツリービューの作成
    tree = ttk.Treeview(frame)

    # 列インデックスの作成
    tree['columns'] = (0,1,2)
    # 表スタイルの設定(headingsは通常の表形式)
    tree['show'] = 'headings'
    # 各列の設定(インデックス,オプション(今回は幅を指定))
    for i in range(0,3):
        tree.column(i,width=100)

    # 各列のヘッダー設定(インデックス,テキスト)
    tree.heading(0, text='項目1')
    tree.heading(1, text='項目2')
    tree.heading(2, text='項目3')

    for i in range(0, len(df)):
        item1 = df.iloc[i][0]
        item2 = df.iloc[i][1]
        item3 = df.iloc[i][2]

        # レコードの作成
        # 1番目の引数-配置場所(表形式の表示ではブランクとする)
        # 2番目の引数-end:表の配置順序を最下部に配置
        # (行インデックス番号を指定することもできる)
        # 3番目の引数-values:レコードの値をタプルで指定する 
        tree.insert('', 'end', values=(item1, item2, item3))

    # ツリービューの配置
    tree.grid(row=0)

    # 保存ボタン
    def save():
        fld = tk.filedialog.askdirectory(initialdir = 'C:') 
        df.to_csv(fld + '/table.csv', encoding='shift-jis', index=False)

    button = ttk.Button(root,
                        text='保存',
                        command=save)
                        button.grid(row=2, pady=5)

    root.mainloop()

if __name__ == '__main__':
    Input()

コメント

タイトルとURLをコピーしました