Python GUI 树遍历

2 投票
2 回答
4868 浏览
提问于 2025-04-17 13:15

我正在尝试弄明白如何遍历一个树形结构,然后把结果显示在一个窗口里,用户可以像在我电脑左侧那样进行浏览。最终,我希望能有一个完全可以浏览的窗口,就像右侧那样。到目前为止,我的进展是这样的,我想这算是伪代码和实际代码的混合。这是为了在使用Python的Linux机器上实现的。我并不想要具体的代码,主要是想知道如何用tkinter来实现这个功能。也许是我自己找不到合适的帮助,大多数资料只是告诉我如何显示目录等等。任何帮助都会非常感激。

我希望这个窗口看起来像这样

My Documents <--------starting directory
    My pictures<------subdirectory
        picture1.jpg<-inside of subdirectoy
        picture2.jpg
    1234.exe<---------random file inside of my documents

我还想在目录或子目录旁边有一个小文件夹的图标。

start at root
     create window with tk
     for dirname,subdirList,filelist in os.walk(root)
     create new item(dirname)   
     for i in subdirList:         #not sure what I would have to do to only    
                                           have subdirs showing once the directory was
                                           clicked once
        append i to item 1       
    for fname in fileList:          
        append fname to item 1      
    else:                    
        item +=1            

2 个回答

-2

我觉得用tkinter来做这个不是个好主意。像wxPython、PyQt或者GTK这样的其他库有很多现成的界面组件,可以让你更轻松地完成这个任务。

4

你可以使用一个叫做 ttk.Treeview 的小工具来实现这个功能,里面有个示例文件 dirbrowser.py 是专门用来演示的。所以我在这里能做的就是给你一个简化版的代码,并解释它是怎么工作的。首先,这里是简短的版本:

import os
import sys
import Tkinter
import ttk

def fill_tree(treeview, node):
    if treeview.set(node, "type") != 'directory':
        return

    path = treeview.set(node, "fullpath")
    # Delete the possibly 'dummy' node present.
    treeview.delete(*treeview.get_children(node))

    parent = treeview.parent(node)
    for p in os.listdir(path):
        p = os.path.join(path, p)
        ptype = None
        if os.path.isdir(p):
            ptype = 'directory'

        fname = os.path.split(p)[1]
        oid = treeview.insert(node, 'end', text=fname, values=[p, ptype])
        if ptype == 'directory':
            treeview.insert(oid, 0, text='dummy')

def update_tree(event):
    treeview = event.widget
    fill_tree(treeview, treeview.focus())

def create_root(treeview, startpath):
    dfpath = os.path.abspath(startpath)
    node = treeview.insert('', 'end', text=dfpath,
            values=[dfpath, "directory"], open=True)
    fill_tree(treeview, node)


root = Tkinter.Tk()

treeview = ttk.Treeview(columns=("fullpath", "type"), displaycolumns='')
treeview.pack(fill='both', expand=True)
create_root(treeview, sys.argv[1])
treeview.bind('<<TreeviewOpen>>', update_tree)

root.mainloop()

这个程序首先会列出你在 sys.argv[1] 提供的路径下的所有文件和文件夹。这里不需要用 os.walk,因为我们只想显示当前路径下的内容,不需要深入到更深的文件夹里。接着,代码会展示这些内容,对于文件夹,它会创建一个虚拟的子节点,这样在 Treeview 中就会显示成可以展开的样子。然后,你可能会注意到有一个绑定到虚拟事件 <<TreeviewOpen>>,这个事件会在用户点击可以展开的项目(在这里就是代表文件夹的条目)时触发。当这个事件被触发时,代码会删除之前创建的虚拟节点,然后用指定文件夹里的内容来填充这个节点。剩下的代码则是关于如何在 Treeview 中存储额外信息,以确保一切正常工作。

撰写回答