現在、独自のプロジェクト ファイルとサブファイルのような内部を持つプログラムに取り組んでおり、ツリービュー ウィジェットを使用してプロジェクト ファイル内のすべてのサブファイルを表示する方法を知りたいのですが、アイデアはありますか?
前もって感謝します!
Treeview にディレクトリの内容を再帰的に入力する方法の CPython のソース コードの例があります。
import os
import tkinter as tk
import tkinter.ttk as ttk
class App(tk.Frame):
def __init__(self, master, path):
tk.Frame.__init__(self, master)
self.tree = ttk.Treeview(self)
ysb = ttk.Scrollbar(self, orient='vertical', command=self.tree.yview)
xsb = ttk.Scrollbar(self, orient='horizontal', command=self.tree.xview)
self.tree.configure(yscroll=ysb.set, xscroll=xsb.set)
self.tree.heading('#0', text=path, anchor='w')
abspath = os.path.abspath(path)
root_node = self.tree.insert('', 'end', text=abspath, open=True)
self.process_directory(root_node, abspath)
self.tree.grid(row=0, column=0)
ysb.grid(row=0, column=1, sticky='ns')
xsb.grid(row=1, column=0, sticky='ew')
self.grid()
def process_directory(self, parent, path):
for p in os.listdir(path):
abspath = os.path.join(path, p)
isdir = os.path.isdir(abspath)
oid = self.tree.insert(parent, 'end', text=p, open=False)
if isdir:
self.process_directory(oid, abspath)
root = tk.Tk()
path_to_my_project = # ...
app = App(root, path=path_to_my_project)
app.mainloop()
更新: @ArtOfWarfare が言及しているように、<<TreeviewOpen>>
イベントを使用してツリーに遅延入力することが可能です。閉じたノードをシミュレートするために、ディレクトリが開かれたときに削除される空の子項目を使用しました。
import os
import tkinter as tk
import tkinter.ttk as ttk
class App(object):
def __init__(self, master, path):
self.nodes = dict()
frame = tk.Frame(master)
self.tree = ttk.Treeview(frame)
ysb = ttk.Scrollbar(frame, orient='vertical', command=self.tree.yview)
xsb = ttk.Scrollbar(frame, orient='horizontal', command=self.tree.xview)
self.tree.configure(yscroll=ysb.set, xscroll=xsb.set)
self.tree.heading('#0', text='Project tree', anchor='w')
self.tree.grid()
ysb.grid(row=0, column=1, sticky='ns')
xsb.grid(row=1, column=0, sticky='ew')
frame.grid()
abspath = os.path.abspath(path)
self.insert_node('', abspath, abspath)
self.tree.bind('<<TreeviewOpen>>', self.open_node)
def insert_node(self, parent, text, abspath):
node = self.tree.insert(parent, 'end', text=text, open=False)
if os.path.isdir(abspath):
self.nodes[node] = abspath
self.tree.insert(node, 'end')
def open_node(self, event):
node = self.tree.focus()
abspath = self.nodes.pop(node, None)
if abspath:
self.tree.delete(self.tree.get_children(node))
for p in os.listdir(abspath):
self.insert_node(node, p, os.path.join(abspath, p))
if __name__ == '__main__':
root = tk.Tk()
app = App(root, path='.')
root.mainloop()
インポートは、Python 3.4 以降をサポートする 2 行目と 3 行目で、次の方法で変更できます。
import tkinter as tk
import tkinter.ttk as ttk
Python 3.4 以降では Tkinter が認識されなくなったため、tkinter では大文字の T を小文字の t に置き換えます。「認識されない参照」エラーを排除します。
新しい Python リリースの完全修飾インポート ディレクティブは、全体的にドット表記に関してより厳密であるため、ttk として tkinter.ttk が必要であり、完全修飾参照を繰り返し行う必要がなくなります。警告: import tk.ttk で十分だと思われるかもしれませんが、どういうわけか参照エラーが発生します。過剰なポインターと条件付きマクロ処理を排除することで、上記の形式を選択するようになりました。他にも可能性はありますが、これが最も使いやすい形式です。
path_to_my_project = # ... エラーが発生しますが、単なるプレースホルダー (まだ機能します) であり、次のように変更できます。
path_to_my_project = "" # ...
Windows でスクリプトを実行すると、バックスラッシュを使用したリテラル ファイル パスでエラーが発生することに注意してください。次のように、前にバックスラッシュ (2 つのバックスラッシュ) を付けて、ファイル パス url のバックスラッシュをエスケープする必要があります。
path_to_my_project = "C:\\Users\\userName\\Desktop\\projDir" #Windows file paths
バックスラッシュを使用してファイル パス内のバックスラッシュをエスケープすると、"C:\Users" が Users の制御文字 U のエスケープに解決される "Unicode エスケープ文字" エラーが解消されます。同じエラーが発生するため、パスを文字列としてキャストしても機能しないため、次のようにします。
path_to_my_project = str("C:\Users\userName\Desktop\projDir")
...無効です。
スクリプトの例 (上記) は、Windows 10 64 ビットで実行される Python 3.4 64 ビットに対してこれらの変更を加えても問題なく動作し、非常にクリーンで安定しています。
私はそれが好きです-エラー、警告、または説明のつかない回避策、BS、およびハックなしで、ほとんど労力(単純な更新)で実行されます。いいぞ。