2 回答

TA貢獻1895條經驗 獲得超3個贊
CPython的源代碼中有一個示例,說明如何用目錄的內容遞歸地填充Treeview,這基本上是它的工作方式(為了更好的可讀性,我刪除了事件綁定并將其包裝在一個類中):
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()

TA貢獻1802條經驗 獲得超10個贊
可以通過以下方式在支持Python 3.4及更高版本的第二行和第三行更改導入:
import tkinter as tk
import tkinter.ttk as ttk
tkinter中的小寫字母t代替了Tkinter中的大寫字母T,因為Python 3.4及更高版本不再識別Tkinter;消除了“無法識別的參考”錯誤。
在較新的Python發行版中,完全合格的導入指令對所有點符號都更加嚴格,因此tkinter.ttk是ttk所必需的,從而消除了對重復的完全合格引用的需求。告誡:有人認為導入tk.ttk就足夠了,但是以某種方式引起了參考錯誤;消除過多的指針和有條件的宏處理使我選擇了上面的格式-還有其他可能,但這是最容易使用的形式。
path_to_my_project =#...會引發錯誤,但僅是占位符(盡管仍然可以使用),可以更改為以下內容:
path_to_my_project = "" # ...
請記住,如果在Windows中運行腳本,則使用反斜杠的文字文件路徑會引發錯誤。您必須使用前面的反斜杠(雙反斜杠)對文件路徑url中的反斜杠進行轉義,如下所示:
path_to_my_project = "C:\\Users\\userName\\Desktop\\projDir" #Windows file paths
在文件路徑中使用反斜杠轉義反斜杠可以消除“ Unicode轉義字符”錯誤,其中“ C:\ Users”解析為在“用戶”中轉義控制字符U,而這并不是我們最初想要的。將路徑轉換為字符串將無法工作,因為會引發相同的錯誤,因此:
path_to_my_project = str("C:\Users\userName\Desktop\projDir")
...無效。
上面的腳本示例針對在Windows 10 64bit上運行的Python 3.4 64bit進行了這些修改,沒有任何問題,并且非常干凈,可靠。
我喜歡它-輕松運行(簡單的更新),沒有錯誤,警告或無法解釋的解決方法,bs和hacks。豎起大拇指。
添加回答
舉報