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

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

【スポンサーリンク】



tkinter.ttk Treeviewの使い方 Python

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

目次

Treeviewの概要

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

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

f:id:vigilantPotato:20190303225421j:plain

例として、カレントディレクト内のファイル名及びサブフォルダ名を表示させています。 また、サブフォルダ横の「+」をクリックすれば、その中身も表示されます。

次は、このTreeviewを用いて簡単なアプリを作成して、使い方を確認していきます。

アプリ概要

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

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

最初に完成したアプリの起動時の画面を以下に示します。 上から、親フォルダ名表示用のラベル、ファイル名表示用のラベル、Treeviewが表示されています。

f:id:vigilantPotato:20190303225421j:plain

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

f:id:vigilantPotato:20190303225524j:plain

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

f:id:vigilantPotato:20190303225541j:plain

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

f:id:vigilantPotato:20190303225601j:plain

Treeviewを用いて、フォルダ内のファイル・サブフォルダの可視化と、クリックによるファイル名・親フォルダ名の取得をすることができました。

コードの解説

作成したアプリのコードを確認します。

まずはモジュールのインポートからです。tkinteとttkをインポートします。 また、ファイルのパスを操作するので、osモジュールもインポートしておきます。

import tkinter
from tkinter import ttk
import os

次は、Treeviewを表示するクラスを作成していきます。

クラス名は「TestTreeview」とし、「ttk.Labelframe」を継承させます。作成するメソッドは、以下の3つです。

  1. __init__:ラベルとTreeviewの生成
  2. process_directoryディレクトリ内のファイル名を取得し、Treeviewに渡す
  3. show_selected:選択されたファイル名とその親フォルダ名を上部のラベルに表示

以下に、「TestTreeview」クラスのコードを示します。

class TestTreeview(ttk.Labelframe):
    def __init__(self, master=None):
        '''LabelとTreeviewの表示'''
        super().__init__(master, text="Treebox")
        
        #親フォルダ名表示用ラベル
        self.folder_name = tkinter.Label(self, text="folder name", bg='lightblue')
        self.folder_name.pack()

        #ファイル名表示用ラベル
        self.file_name = tkinter.Label(self, text="file name", bg='lightyellow')
        self.file_name.pack()

        #Treeview
        self.tree = ttk.Treeview(self) #1
        self.tree.bind("<<TreeviewSelect>>", self.show_selected) #2
        path = os.getcwd()
        root_node = self.tree.insert("", "end", text=path, open=True) #3
        self.process_directory(root_node, path) #4
        self.tree.pack()

    def process_directory(self, parent, path):
        '''ディレクトリ内のファイル名を表示するメソッド'''
        for p in os.listdir(path): #1
            abspath = os.path.join(path, p) #2
            oid = self.tree.insert(parent, "end", text=p, open=False) #3
            isdir = os.path.isdir(abspath) #4
            if isdir: #5
                self.process_directory(oid, abspath)

    def show_selected(self, event):
        '''選択したファイル名とその親フォルダをラベルに表示するメソッド'''
        curItem = self.tree.focus() #1
        parentItem = self.tree.parent(curItem) #2
        self.folder_name["text"] = self.tree.item(parentItem)["text"] #3
        self.file_name["text"] = self.tree.item(curItem)["text"] #4

initメソッド

ここでは、まずファイル名・親フォルダ名表示用のラベルを生成し、その後、以下の順番でTreeviewの生成と設定をしています。

  1. Treeviewの生成
  2. ファイル名選択時に、「show_selected」メソッドが実行されるように設定
  3. 表示させるフォルダのパスを設定(カレントディレクトリ)
  4. 「process_directory」メソッドを実行して、フォルダ内のファイル名を取得・表示

process_directoryメソッド

  1. パス内のファイル、サブフォルダ名を取得
  2. 絶対パスを生成
  3. Treeviewに追加・表示
  4. 絶対パスがファイルかサブフォルダかを判定
  5. サブフォルダの場合、「process_directory」メソッドを再帰呼び出しして、サブフォルダ内のファイル名を取得

show_selectedメソッド

このメソッドは、Treeview内のファイル名・フォルダ名がクリックされた際に実行されます。

  1. 選択されているファイル名・フォルダ名を取得
  2. 選択されているファイル名・フォルダ名の「親フォルダ名」を取得
  3. 上部のラベルにファイル名・フォルダ名を表示
  4. 上部のラベルに親フォルダ名を表示

以上で「TestTreeview」クラスに関するコードは完成です。

最後に、「TesTreeview」クラスを生成する以下のコードを追加します。

if __name__ == "__main__":
    root = tkinter.Tk()
    f = TestTreeview(master=root)
    f.pack()
    root.mainloop()

コード全文

import tkinter
from tkinter import ttk
import os

class TestTreeview(ttk.Labelframe):
    def __init__(self, master=None):
        '''LabelとTreeviewの表示'''
        super().__init__(master, text="Treebox")
        
        #親フォルダ名表示用ラベル
        self.folder_name = tkinter.Label(self, text="folder name", bg='lightblue')
        self.folder_name.pack()

        #ファイル名表示用ラベル
        self.file_name = tkinter.Label(self, text="file name", bg='lightyellow')
        self.file_name.pack()

        #Treeview
        self.tree = ttk.Treeview(self)
        self.tree.bind("<<TreeviewSelect>>", self.show_selected)
        path = os.getcwd()
        root_node = self.tree.insert("", "end", text=path, open=True)
        self.process_directory(root_node, path)
        self.tree.pack()
        
    def process_directory(self, parent, path):
        '''ディレクトリ内のファイル名を表示するメソッド'''
        for p in os.listdir(path):
            abspath = os.path.join(path, p)
            oid = self.tree.insert(parent, "end", text=p, open=False)
            isdir = os.path.isdir(abspath)
            if isdir:
                self.process_directory(oid, abspath)

    def show_selected(self, event):
        '''選択したファイル名とその親フォルダをラベルに表示するメソッド'''
        curItem = self.tree.focus()
        parentItem = self.tree.parent(curItem)
        self.folder_name["text"] = self.tree.item(parentItem)["text"]
        self.file_name["text"] = self.tree.item(curItem)["text"]

if __name__ == "__main__":
    root = tkinter.Tk()
    f = TestTreeview(master=root)
    f.pack()
    root.mainloop()