【Python】tkinter:テーブル(表)の作成方法(ttk.Treeview)

2021.10.23 /

【Python】tkinter:テーブル(表)の作成方法(ttk.Treeview)

本記事ではPythonのtkinterにおける、テーブル)の作成方法について解説していきます。

sqlite3やMySQLといったデータベースを利用したデスクトップアプリケーションの場合、たいていテーブル(表)を使用することが多いです。

データベースに保存されているデータを一覧表示するような使い方でテーブルを利用します。

tkinterに用意されているウィジェットの一つ、ttk.Treeviewを利用すると簡単に階層表示やテーブルを作成できます。

ぜひTreeviewウィジェットの使い方を学んで、アプリにテーブルを埋め込んでみましょう。

Treeviewによる階層表示やTreeviewウィジェットについては以下記事をご参照ください。

またTkinterの基本的な使用方法については以下記事をご参照ください。

テーブル(表)作成の基本の流れ

tkinterによるテーブル(表)を作成するための基本的な流れを解説します。ここでは以下に示すコードを元に解説していきます。

# サンプルコード
import tkinter as tk
from tkinter import ttk

# 列の識別名を指定
column = ('ID', 'Name', 'Score')
# メインウィンドウの生成
root = tk.Tk()
root.title('Score List')
root.geometry('400x300')
# Treeviewの生成
tree = ttk.Treeview(root, columns=column)
# 列の設定
tree.column('#0',width=0, stretch='no')
tree.column('ID', anchor='center', width=80)
tree.column('Name',anchor='w', width=100)
tree.column('Score', anchor='center', width=80)
# 列の見出し設定
tree.heading('#0',text='')
tree.heading('ID', text='ID',anchor='center')
tree.heading('Name', text='Name', anchor='w')
tree.heading('Score',text='Score', anchor='center')
# レコードの追加
tree.insert(parent='', index='end', iid=0 ,values=(1, 'KAWASAKI',80))
tree.insert(parent='', index='end', iid=1 ,values=(2,'SHIMIZU', 90))
tree.insert(parent='', index='end', iid=2, values=(3,'TANAKA', 45))
tree.insert(parent='', index='end', iid=3, values=(4,'OKABE', 60))
tree.insert(parent='', index='end', iid=4, values=(5,'MIYAZAKI', 99))
# ウィジェットの配置
tree.pack(pady=10)

root.mainloop()
tkinter:テーブル(表)を作成

このアプリにおける「見出し」と「レコード」は次のようになります。

tkinter:テーブルの見出しとレコード

Treeviewオブジェクトの生成

以下に示すコンストラクタを使ってTreeviewオブジェクトを生成します。

構文

ttk.Treeview(container, **options)

引数 説明
container 親ウィジェットを指定
options オプションを指定(複数可)

生成したTreeviewオブジェクトを使ってテーブル(表)を作成していきます。以下にTreeviewで指定できるオプション引数を記します。

キーワード引数 説明
columns 列の識別名
displaycolumns 表示する列の指定及び順番
show 表示する対象
・tree:階層列
・headings:見出し)
*デフォルト値は両方(['tree', 'headings'])
selectmode 選択できる要素数
・EXTENDED:複数選択可能(デフォルト)
・BROWSE:一つのみ選択
・NONE:選択不可
height 表示する行数
padding 内部間隔(パディング)の指定
cursor カーソルの指定
style スタイルの指定
xscrollcommand x方向のスクロール呼び出し関数
yscrollcommand y方向のスクロール呼び出し関数

サンプルコードでは次のようにしてTreeviewオブジェクトを生成しています。

tree = ttk.Treeview(root, columns=column)

上記ではオプションcolumnsで事前に作成していたcolumnを代入し、各列の識別名を指定しています。

各列の識別名を設定することで、列の設定・見出しの設定・アイテムの追加などの管理ができます。

列の設定

次に各列の横幅やテキストの配置位置など細かな設定を行います。

Treeviewオブジェクトに対してcolumn()メソッドを使用することで各列のオプション情報の取得や設定が行えます。

構文

column(column, options)

引数columnにはTreeviewオブジェクトの生成時に指定した列の識別名を指定します。

引数optionsには以下に示すオプションを複数指定できます。

オプション名 説明
anchor テキストの配置位置
id 列名
minwidth 列の最小幅(デフォルト値:20ピクセル)
stretch 列幅の変更可否(TrueまたはFalse)
width 列の横幅(デフォルト値:200ピクセル)

サンプルコードでは以下のように列の設定を行っています。

# 列の設定
tree.column('#0',width=0, stretch='no')
tree.column('ID', anchor='center', width=80)
tree.column('Name',anchor='w', width=100)
tree.column('Score', anchor='center', width=80)

列の見出しの設定:heading()メソッド

Treeviewオブジェクトを生成する際にオプションshowでheadings(デフォルトでは指定済み)が指定されていると、見出しを指定することができます。

構文

heading(column, options)

引数columnには列の識別名を指定します。列名#0は階層列を表します。

optionsには以下のオプションを指定できます。

オプション名 説明
anchor 文字列の配置
command 紐づける関数を指定
image 見出しの右側に表示する画像
text 見出しのテキスト

サンプルコードでは次のようにして見出しを設定しています。

# 列の見出し設定
tree.heading('#0',text='')
tree.heading('ID', text='ID',anchor='center')
tree.heading('Name', text='Name', anchor='w')
tree.heading('Score',text='Score', anchor='center')

階層列#0は今回利用しないので、オプションtextは空文字にします。

その他の列は、識別名を第一引数に指定し、オプションtextで表示する列名、オプションanchorで配置位置を指定します。

レコードの追加

レコードの追加にはinsert()メソッドを使用します。

構文

insert(parent, index, iid=None, options)

テーブル(表)にレコードを追加する場合、引数parentには空文字を指定します。

引数indexには文字列の挿入位置を指定します。末尾に挿入する場合は、"end"を指定します。

引数iidは挿入するアイテムのアイテムIDを意味します。iidを省略すると、自動的に生成されます。
サンプルコードではiidを指定していますが、省略して問題ないです。

insert()メソッドの戻り値はiidです。

optionsには以下のオプションを指定できます。

オプション名 説明
image 画像の指定
open 子要素を展開した状態するか
・False:子要素を展開しない
・True:子要素を展開した状態にする
tags タグ名を指定
text 挿入するテキストを指定
values データ列の値(リスト)

サンプルコードでは次のようにしてレコードを追加しています。

# レコードの追加
tree.insert(parent='', index='end', iid=0 ,values=(1, 'KAWASAKI',80))
tree.insert(parent='', index='end', iid=1 ,values=(2,'SHIMIZU', 90))
tree.insert(parent='', index='end', iid=2, values=(3,'TANAKA', 45))
tree.insert(parent='', index='end', iid=3, values=(4,'OKABE', 60))
tree.insert(parent='', index='end', iid=4, values=(5,'MIYAZAKI', 99))

オプションvaluesで追加するレコードの値を設定します。

テーブルのレコード値を変更する

ここでは選択したレコードの値を変更させるプログラムについて解説します。

以下にボタンをクリックするとレコードの値が変化するスクリプトのサンプルコードを記します。

# サンプルコード
import tkinter as tk
from tkinter import ttk

def up_price():
    selected = tree.focus()
    temp = tree.item(selected, 'values')
    sal_up = float(temp[2]) + float(temp[2]) * 0.1
    tree.item(selected, values=(temp[0], temp[1], sal_up))

# メインウィンドウの生成
root = tk.Tk()
root.title("レコード値の変更")
# Treeviewの生成
tree = ttk.Treeview(root, columns=(1, 2, 3), show='headings', height=8)
# 列の見出し設定
tree.heading(1, text="id")
tree.heading(2, text="vegetable")
tree.heading(3, text="price")
# レコードの追加
tree.insert(parent='', index=0, iid=0, values=(1, "onion", 30.00))
tree.insert(parent='', index=1, iid=1, values=(2, "cabbage", 150.00))
tree.insert(parent='', index=2, iid=2, values=(3, "carrot", 80.00))
tree.insert(parent='', index=3, iid=3, values=(4, "eggplant", 100.00))
# Buttonの生成
button = Button(root, text='Increment Price', command=up_price)
# Styleの設定
style = ttk.Style()
style.theme_use("default")
style.map("Treeview")
# ウィジェットの配置
tree.pack()
button.pack()

ws.mainloop()
tkinter:テーブルのレコード値を変更する

このプログラムは、「Increment Price」ボタンを押すと、選択しているレコードのPrice列が増加する仕組みです。

ここで使われているメソッドについて次項より解説していきます。

選択されたレコードのアイテムIDの取得:focus()メソッド

サンプルコードではButtonを押すと関数up_price()が実行されます。関数up_price()ではまず選択されたレコードを識別します。

選択されたレコードの識別にfocus()メソッドを使用します。
focus()メソッドは選択されたレコードのアイテムIDを返します。

構文

focus(item=None)

focus()メソッドの引数itemにアイテムIDを指定すると、フォーカスを設定します。
引数itemをなにも指定しなければ、現在フォーカスされているレコードのアイテムIDを戻り値とします。

サンプルコードでは次のように記述しています。

selected = tree.focus()

focus()メソッドで得たアイテムIDを変数selectedに代入しています。
次にこの変数を使ってレコード値を取得します。

アイテムIDからレコード値を取得:item()メソッド

取得したアイテムIDからレコード値(values)を取得するためにitem()メソッドを使用します。

item()メソッドでは、指定したアイテム(レコード)のオプション値を設定または取得ができます。

構文

item(item, option=None, **kw)

引数itemにはアイテムIDを指定します。
引数kwには取得したいオプション名を指定します。引数kwを省略すると、全オプション値を取得します。

サンプルコードでは次のように記述しています。

temp = tree.item(selected, 'values')

item()メソッドの引数にアイテムIDを保持したselected、レコード値を指定しているvaluesをそれぞれ指定しています。

テーブル(表)のレコード値を変更:item()メソッド

最後にレコードの値を変更します。現在のレコード値valuesは、取得したオプション値から取得・変更できます。

sal_up = float(temp[2]) + float(temp[2]) * 0.1
  tree.item(selected, values=(temp[0], temp[1], sal_up))
  

上記のようにtemp[0]、temp[1]とすることで、アイテムのタプルから値を取得します。

そしてitem()メソッドを利用して、valuesの値を変更します。結果、レコード値が変わるということです。

スクロールバーを追加する

ここではテーブルにスクロールバーを追加します。

以下に上記で作成したテーブルにスクロールバーを追加したスクリプトのサンプルコードを記します。

import tkinter as tk
from tkinter import ttk

def up_price():
    selected = tree.focus()
    temp = tree.item(selected, 'values')
    sal_up = float(temp[2]) + float(temp[2]) * 0.1
    tree.item(selected, values=(temp[0], temp[1], sal_up))

# メインウィンドウの生成
root = tk.Tk()
root.title("レコード値の変更")

frame = Frame(root)
# Treeviewの生成
tree = ttk.Treeview(frame, columns=(1, 2, 3), show='headings', height=4)
# 列の見出し設定
tree.heading(1, text="id")
tree.heading(2, text="vegetable")
tree.heading(3, text="price")
# レコードの追加
tree.insert(parent='', index=0, iid=0, values=(1, "onion", 30.00))
tree.insert(parent='', index=1, iid=1, values=(2, "cabbage", 150.00))
tree.insert(parent='', index=2, iid=2, values=(3, "carrot", 80.00))
tree.insert(parent='', index=3, iid=3, values=(4, "eggplant", 100.00))
tree.insert(parent='', index=4, iid=4, values=(5, "green pepper", 100.00))
tree.insert(parent='', index=5, iid=5, values=(6, "Bean sprouts", 100.00))
# Buttonの生成
button = Button(root, text='Increment Price', command=up_price)
# Styleの設定
style = ttk.Style()
style.theme_use("default")
style.map("Treeview")
# スクロールバーの追加
scrollbar = ttk.Scrollbar(frame, orient=tk.VERTICAL, command=tree.yview)
tree.configure(yscroll=scrollbar.set)
# ウィジェットの配置
frame.pack()
tree.pack(side=LEFT)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
button.pack()

ws.mainloop()
tkinter:テーブルにスクロールバーを追加

まとめ

本記事「【Python】tkinter:テーブル(表)の作成方法(Treeview)」はいかがでしたか。

Treeviewウィジェットを利用してユーザビリティに優れたGUIアプリケーションを作成してみてください。