【问题标题】:Tkinter Treeview for Tarfile itemsTarfile 项目的 Tkinter 树视图
【发布时间】:2020-04-11 16:32:07
【问题描述】:

我在编写一个函数时遇到了麻烦,该函数可以通过.getmembers() 方法获取 tarfile 项目列表并将它们放在 Treeview 小部件中的适当树结构(文件夹和子文件夹中的文件)中。我找到了一个与我想要的类似的帖子:Tkinter: Treeview widget,但我无法让它适应查看档案。
我引用的解决方案的问题是它使用os 遍历给定目录并将项目插入树视图。当然,这对 tarfile 不起作用,因为它是一个文件,而不是文件夹,所以当我尝试修改解决方案时,我将 tarfile 成员存储在一个列表中并尝试通过该函数提供它,但它对我不起作用。

基本上,我需要帮助编写一个函数,该函数采用目录和文件名列表,可以将父目录插入树视图的根目录,并将子项插入其包含的文件夹。

import os
import tkinter as tk
import tkinter.ttk as ttk
import tarfile

window = tk.Tk()
window.title("Testing")
window.geometry("500x500")

tree = ttk.Treeview(window)
tree.pack()
tree.heading('#0', text="Item")
tree.column('#0', width=495)

# Get TAR items
with tarfile.TarFile("testing.tar") as topen:
    tarlist = topen.getmembers()

# Get our first directory in the list and remove it from stack
for i in tarlist:
    if i.isdir() == True:
        start_node = i.name
        del tarlist[tarlist.index(i)]
        break

# Insert root folder
root_node = tree.insert('', 'end', text=start_node)

def insert():
    # Go through the rest of the member list and put the member in the proper place
    # within the tree structure

window.mainloop()

【问题讨论】:

  • "它只是不适合我" 您能否在此处添加带有 Traceback 错误的函数?
  • 好吧,如果你想要一些回溯,我使用了下面建议的解决方案,它给出了“项目 pylzma-master/pylzma-master/src 已经存在”。但是我假设您在谈论我之前所拥有的内容,因为我无法按 Ctrl-Z 回到它,所以我无法真正获得我原来的最佳解决方案。基本上没有回溯错误;它只是以一种不受欢迎的方式显示内容。我最初的解决方案使用 os.dirname 的某种组合来获取树项的目录名并将其与列表项的目录名进行比较以确定它是否是子项,它是混乱和钝的。
  • 另外,我理解我提出问题的方式就像“为我制作这个函数”,但我花了很多时间试图弄清楚我写的每个函数都没有给我想要的结果.选择一个放在我的代码示例中会很困难,只会添加不需要的绒毛。谢谢,祝您有愉快的一天!

标签: python tkinter treeview tarfile


【解决方案1】:

感谢 j_4321,这就是我为得到我想要的东西所做的事情。我将 tarlist 拆分为 tardirs 和 tarfiles 列表,然后首先添加 tardirs,因为我希望它们按层次排序。接下来是 Tarfiles 并被插入到适当的位置。我使用异常处理程序来捕获文件与目录同名的任何异常,并避免在该实例中使用 iid。结果是一个结构良好的 TAR 存档视图,接下来将在标识为目录的项目旁边添加文件夹图标,以及不让它看起来像样的东西。

tardirs = []
tarfiles = []

for i in tarlist:
    if i.isdir() == True:
        tardirs.append(i)
    else:
        tarfiles.append(i)

def insert():
    for item in tardirs:
        parent, label = os.path.split(item.path)
        try:
            tree.insert(parent, 'end', iid=item.path, text=label)
        except Exception:
            tree.insert(parent, 'end', text=label)
    for item in tarfiles:
        parent, label = os.path.split(item.path)
        try:
            tree.insert(parent, 'end', iid=item.path, text=label)
        except Exception:
            tree.insert(parent, 'end', text=label)

【讨论】:

  • 对于图标,很简单,插入项目时使用image选项即可。
【解决方案2】:

这个想法是使用完整项目的路径作为其在树中的 iid,以便您可以使用 parent, label = os.path.split(item.path) 获取项目的父项和项目的标签。

根据.getmembers() docstring,

将归档的成员作为 TarInfo 对象列表返回。这 列表与存档中的成员具有相同的顺序。

因此,您不必担心存在父级,如果您使用 for 循环通过 tarlist,它将在之前创建,如下面的代码中所示。

import os
import tkinter as tk
import tkinter.ttk as ttk
import tarfile

window = tk.Tk()
window.title("Testing")
window.geometry("500x500")

tree = ttk.Treeview(window)
tree.pack()
tree.heading('#0', text="Item")
tree.column('#0', width=495)

# Get TAR items
with tarfile.TarFile("testing.tar") as topen:
    tarlist = topen.getmembers()


def insert():
    for item in tarlist:
        parent, label = os.path.split(item.path)
        tree.insert(parent, 'end', iid=item.path, text=label)

insert()
window.mainloop()

【讨论】:

  • 这在一定程度上有效,但它无法显示位于 Tarfile 基础级别的文件。这一定是因为我遇到了一个我必须捕获的错误,即“项目 pylzma-master/pylzma-master/src 已经存在”所以我要打印列表并找出导致错误的原因,我'我会回复你的。这比使用 os.dirname 并使用 tree.item('text') 获取名称并查看该项目是否为子项目要简单得多。谢谢。
  • 好吧,只是做了一些调查工作,出现错误是因为上面所说的项目有一个副本,但是因为其中一个是目录,另一个是没有扩展名的文件,但它被视为所述目录的副本。我想知道这是否可以使用 tarfile 模块中的 .isdir() 方法来规避?检测什么是目录,什么是文件,不管扩展名/名称。
  • 我接受您的回答,因为您是帮助我实现目标的人,非常感谢。我还发布了一个答案,显示了我做了哪些修改以根据自己的喜好对其进行微调并排除任何异常。再次感谢您,祝您有美好的一天。
  • @Jimmy-John 谢谢,很高兴能帮上忙。
猜你喜欢
  • 2017-07-07
  • 2020-10-22
  • 1970-01-01
  • 2021-01-28
  • 1970-01-01
  • 2015-10-25
  • 1970-01-01
  • 1970-01-01
  • 2020-10-20
相关资源
最近更新 更多