簡體   English   中英

使用 tkinter Treeview 小部件顯示目錄內容

[英]Display directory content with tkinter Treeview widget

目前我正在開發一個程序,它有自己的項目文件,里面有子文件,我想知道如何使用樹視圖小部件來顯示項目文件中的所有子文件,有什么想法嗎?

提前致謝!

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()

可以通過以下方式在支持 Python 3.4 及更高版本的第二行和第三行更改導入:

import tkinter as tk
import tkinter.ttk as ttk

tkinter 中的小寫 t 替換了 Tkinter 中的大寫 T,因為 Python 3.4 及更高版本不再識別 Tkinter; 消除了“無法識別的引用”錯誤。

較新的 Python 版本中的完全限定導入指令對點表示法更加嚴格,因此 tkinter.ttk 作為 ttk 是必需的,並且消除了重復完全限定引用的需要。 警告:人們會假設 import 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 64 位中運行的 Python 3.4 64 位的這些修改,沒有問題,並且非常干凈和可靠。

我喜歡它 -- 毫不費力地運行(簡單的更新),沒有錯誤、警告或無法解釋的變通方法、bs 和 hacks。 豎起大拇指。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM