初心者でもPythonを使ってみよう

趣味と実益を兼ねたPython学習記

【スポンサーリンク】



tkinter.ttk Treeviewの使い方 Python

tkinter.ttkで利用できるTreeviewの使い方を、実際にコードを書きながらまとめました。

目次

Treeviewの概要

Treeviewは、階層構造を持つアイテムツリー表示するためのウィジェットで、あるフォルダ内のファイル構成の可視化に使用されることが多いです。

以下に、tkinter.ttkで生成したTreeviewの外観を示します。

f:id:vigilantPotato:20190525155009p:plain

「Food」、「Softdrink」、「Alcohol」の3つの要素が表示されており、文字横の「+」をクリックすると、子要素が表示されます。

f:id:vigilantPotato:20190525155112p:plain

このように、階層構造を持つアイテムをツリー表示することができます。

Treeviewの基本

インポート

Treeviewを使用するには、tkinterとは別にtkinter.ttkをインポートする必要があります。

例:

import tkinter
from tkinter import ttk


主なメソッド

  1. insert(parent, index, **kw)

    • Treeviewに新しいアイテムを挿入し、その識別番号を返すメソッド。
    • parentは親アイテムの識別番号で、空文字にすると最上位に設定される。
    • indexは整数値または「"end"」で、アイテムを挿入する位置を指定できる。
    • 「kw」でオプション設定が可能。textやopenなど。
  2. focus()

    • 現在選択されているアイテムの識別番号を返すメソッド。
  3. parent(item)

    • 親アイテムの識別番号を返すメソッド。


主なオプション

  1. textオプション

    • 表示するテキストを設定するオプション。
  2. openオプション

    • 子アイテムの表示を設定するオプション。
    • 「True」:表示する
    • 「False」:隠す


Event

  1. TreeviewSelect

    • ツリービューのアイテムを選択したときに発生するイベント


次は、実際に簡単なアプリを作成しながら詳しい使い方を確認していきます。

アプリ概要

以下の辞書を、キーを親アイテム、バリューの各要素を子アイテムとしてツリービューで表示するアプリを作成します。 (Treeviewの概要で例示したものです。)

menu = {
    "Food":["Hamburger", "Beef steak", "Salad"],
    "Softdrink":["Coke", "Cider", "Tea"],
    "Alcohol":["Beer", "Wine", "Cocktail"],
    }

以下が、起動時の画面です。

f:id:vigilantPotato:20190525155009p:plain

各親アイテムをクリックすると、その子アイテムがそれぞれ表示されます。

f:id:vigilantPotato:20190525155112p:plain

階層構造を持つアイテムを、ツリービューで表示することができました。

コードの解説

準備

まずはtkinterとtkinter.ttkをインポートし、トップレベルウィジェットを生成します。

import tkinter
from tkinter import ttk

#1. 辞書表示用ツリービュークラス

if __name__ == "__main__":
    root = tkinter.Tk()

    #2.ツリービューの表示
    
    root.mainloop()


1. 辞書表示用ツリービュークラス

次は、辞書を表示するためのツリービュークラスを生成します。

名前はTestTreeviewとし、ttk.Treeviewを継承させます。

class TestTreeview(ttk.Treeview):
    def __init__(self, master=None):
        super().__init__(master=master)
        menu = {
            "Food":["Hamburger", "Beef steak", "Salad"],
            "Softdrink":["Coke", "Cider", "Tea"],
            "Alcohol":["Beer", "Wine", "Cocktail"],
            }
        
        #辞書のキーを挿入
        for p in menu:
            root_node = self.insert(
                "",     #最上位なのでparentは空文字
                "end",
                text=p,
                )
            #辞書の要素を挿入    
            for m in menu[p]:
                self.insert(
                    root_node,  #parentはキーの認識番号
                    "end",
                    text=m,
                    )

for文を用いて辞書のキーとそのバリューをツリービューに挿入しています。

キーは最上位のアイテムになるので、insertの引数「parent」は空文字です。

また、バリューはキーの子アイテムなので、キーをinsertしたときの戻り値を引数「parent」に渡しています。


2. ツリービューの表示

最後に、「TestTreeview」を生成して完成です。

#2.ツリービューの表示
t = TestTreeview(master=root)
t.pack()

アプリ概要 ファイル構成の表示

応用として、Treeviewを用いて以下の2つの機能を持つアプリを作成していきます。

  1. カレントディレクト内のファイル名、サブフォルダ名をリスト化して表示する。
  2. リスト化された項目をクリックすると、そのファイル名と親フォルダ名を取得してラベルに表示する。

最初に完成したアプリの起動時の画面を以下に示します。 上から、選択したアイテム表示用のラベルと、その親アイテムの表示用のラベル、Treeviewが表示されています。

f:id:vigilantPotato:20190525155520p:plain

ツリービュー内のアイテムをクリックすると、上部のラベルにアイテム名を取得して表示します。

今回の例では、カレントディレクトリ内のファイルは最上位の要素になるため、親アイテム名は空文字になります。

f:id:vigilantPotato:20190525155607p:plain

サブフォルダ横の「+」をクリックすると、サブフォルダ内のファイル名が出現します。

f:id:vigilantPotato:20190525155702p:plain

サブフォルダ内のファイル名をクリックすると、ファイル名とその親フォルダ名を取得して上部のラベルに表示します。

f:id:vigilantPotato:20190525155742p:plain

ツリービューを用いて、フォルダ内のファイル・サブフォルダの可視化と、選択したファイル名・親フォルダ名の取得・表示jをすることができました。

コードの解説 ファイル構成の表示

準備

tkinter、tkinter.ttkと、パスの操作用にosモジュールをインポートし、トップレベルウィジェットを生成します。

import tkinter
from tkinter import ttk
import os

#1. ファイル構造表示用ツリービュークラス

if __name__ == "__main__":
    root = tkinter.Tk()

    #2. ツリービューの表示

    root.mainloop()


1. ファイル構造表示用ツリービュークラス

次に、ファイル構造表示用のツリービュークラスを生成します。名前はFileTreeviewとして、ttk.Treeviewを継承させます。

#1. ファイル構造表示用ツリービュークラス
class FileTreeview(ttk.Treeview):
    def __init__(self, master=None):
        super().__init__(master)
        self.process_directory("", os.getcwd())
        self.bind("<<TreeviewSelect>>", self.show_selected)

        #選択アイテム表示用ラベル
        self.filename = tkinter.Label(
            master=None,
            text="Filename",
            bg="lightblue",
            width=15,
            )
        self.filename.pack()

        #親アイテム表示用ラベル
        self.foldername = tkinter.Label(
            master=master,
            text="Folder",
            bg="lightgreen",
            width=15,
            )
        self.foldername.pack()

    def process_directory(self, parent, path):
        for p in os.listdir(path):
            abspath = os.path.join(path, p)
            oid = self.insert(
                parent,
                "end",
                text=p,
                )
            if os.path.isdir(abspath):
                self.process_directory(oid, abspath)

    def show_selected(self, event):
        curItem = self.focus()              #選択アイテムの認識番号取得
        parentItem = self.parent(curItem)   #親アイテムの認識番号取得
        self.filename["text"] = self.item(curItem)["text"]
        self.foldername["text"] = self.item(parentItem)["text"]
  1. initメソッド

    • カレントディレクト内のファイル・フォルダを取得するprocess_directoryメソッドを実行。
    • TreeviewSelectイベントを用いて、アイテムクリック時にshow_selectedメソッドを実行するように設定。
    • アイテム表示用ラベルの生成
  2. process_directory(self, parent, path)

    • parent:親アイテムの認識番号
    • path:リスト化するフォルダのパス
    • path内のファイル、フォルダをツリービューへ追加(insert)する。
    • フォルダを追加した際は、そのフォルダの認識番号を引数として自分自身を呼び出し(再帰呼び出し)、フォルダ内のファイルもツリービューへ挿入する。
  3. show_selected(self, event)

    • アイテム選択時に発生するTreeviewSelectイベントで実行。
    • 選択したアイテムの認識番号を取得し、テキストとその親要素のテキストをラベルに表示する。


2. ツリービューの表示

最後に、「FileTreeview」を生成して完成です。

#2.ツリービューの表示
t = FileTreeview(master=root)
t.pack()

コード全文

1. 辞書のリスト化

import tkinter
from tkinter import ttk

#1. 辞書表示用ツリービュークラス
class TestTreeview(ttk.Treeview):
    def __init__(self, master=None):
        super().__init__(master=master)
        menu = {
            "Food":["Hamburger", "Beef steak", "Salad"],
            "Softdrink":["Coke", "Cider", "Tea"],
            "Alcohol":["Beer", "Wine", "Cocktail"],
            }
        
        #辞書のキーを挿入
        for p in menu:
            root_node = self.insert(
                "",     #最上位なのでparentは空文字
                "end",
                text=p,
                )
            #辞書の要素を挿入    
            for m in menu[p]:
                self.insert(
                    root_node,  #parentはキーの認識番号
                    "end",
                    text=m,
                    )


if __name__ == "__main__":
    root = tkinter.Tk()

    #2.ツリービューの表示
    t = TestTreeview(master=root)
    t.pack()
    
    root.mainloop()


2. ファイル構造表示

import tkinter
from tkinter import ttk
import os

#1. ファイル構造表示用ツリービュークラス
class FileTreeview(ttk.Treeview):
    def __init__(self, master=None):
        super().__init__(master)
        self.process_directory("", os.getcwd())
        self.bind("<<TreeviewSelect>>", self.show_selected)

        #選択アイテム表示用ラベル
        self.filename = tkinter.Label(
            master=None,
            text="Filename",
            bg="lightblue",
            width=15,
            )
        self.filename.pack()

        #親アイテム表示用ラベル
        self.foldername = tkinter.Label(
            master=master,
            text="Folder",
            bg="lightgreen",
            width=15,
            )
        self.foldername.pack()

    def process_directory(self, parent, path):
        for p in os.listdir(path):
            abspath = os.path.join(path, p)
            oid = self.insert(
                parent,
                "end",
                text=p,
                )
            if os.path.isdir(abspath):
                self.process_directory(oid, abspath)

    def show_selected(self, event):
        curItem = self.focus()              #選択アイテムの認識番号取得
        parentItem = self.parent(curItem)   #親アイテムの認識番号取得
        self.filename["text"] = self.item(curItem)["text"]
        self.foldername["text"] = self.item(parentItem)["text"]


if __name__ == "__main__":
    root = tkinter.Tk()

    #2.ツリービューの表示
    f = FileTreeview(master=root)
    f.pack()
    root.mainloop()