PySimpleGui 树添加带有事件的元素以减少启动时间

PySimpleGui Tree Add Elements with an Event to Reduce Startup Time

我正在尝试将 GUI 添加到我制作的命令行程序中。我需要一个文件树到 select 个程序文件。我找到了一个使用 PySimpleGUI 的程序,但它需要一段时间才能启动,因为它必须递归地遍历文件。

我能够通过限制递归深度并在插入 TreeData 后使用 update(values=treedata) 来解决这个问题。这虽然会重置树(关闭所有打开的展开文件夹)并且是一种糟糕的用户体验。

update 函数还允许您使用 keyvalue 修改节点,但是您可以添加节点并定义它们的父节点吗?我好像找不到 if/how 你这样做。

是否有添加子节点的方法或better/faster向树数据结构添加许多文件的方法?

提前致谢。

循环

while True:  # Event Loop
    event, values = window.read()
    tree.update()
    try:
        v = values[tree_key][0]  # clicked file/folder
        print(v)
    except TypeError:
        pass
    if event == tree_key
        add_files_in_folder(v, v, 2, False)
        tree.update(values=treedata) 

    if event in (sg.WIN_CLOSED, 'Cancel', True):
        break
    print(event, values)

递归

def add_files_in_folder(parent, dirname, recursion_limit, tree_created):
    if recursion_limit != 0:
        try:
            files = os.listdir(dirname)
        except PermissionError:
            return
        if not opened_folders.__contains__(dirname):
            opened_folders.append(dirname)
            for f in files:
                fullname = os.path.join(dirname, f)
                if os.path.isdir(fullname):  # if it's a folder, add folder and recurse
                    treedata.insert(parent, fullname, f, values=[], icon=folder_icon)
                    add_files_in_folder(fullname, fullname, recursion_limit - 1, tree_created)
                else:
                    treedata.insert(parent, fullname, f, values=[os.stat(fullname).st_size], icon=file_icon)

这里的演示代码仅在需要时通过双击加载目录内容。 https://github.com/jason990420/PySimpleGUI-Solution/issues/97

from pathlib import Path
import PySimpleGUI as sg

def new_key():
    key = 1
    while key in data:
        key += 1
    return key

folder_icon = b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAABnUlEQVQ4y8WSv2rUQRSFv7vZgJFFsQg2EkWb4AvEJ8hqKVilSmFn3iNvIAp21oIW9haihBRKiqwElMVsIJjNrprsOr/5dyzml3UhEQIWHhjmcpn7zblw4B9lJ8Xag9mlmQb3AJzX3tOX8Tngzg349q7t5xcfzpKGhOFHnjx+9qLTzW8wsmFTL2Gzk7Y2O/k9kCbtwUZbV+Zvo8Md3PALrjoiqsKSR9ljpAJpwOsNtlfXfRvoNU8Arr/NsVo0ry5z4dZN5hoGqEzYDChBOoKwS/vSq0XW3y5NAI/uN1cvLqzQur4MCpBGEEd1PQDfQ74HYR+LfeQOAOYAmgAmbly+dgfid5CHPIKqC74L8RDyGPIYy7+QQjFWa7ICsQ8SpB/IfcJSDVMAJUwJkYDMNOEPIBxA/gnuMyYPijXAI3lMse7FGnIKsIuqrxgRSeXOoYZUCI8pIKW/OHA7kD2YYcpAKgM5ABXk4qSsdJaDOMCsgTIYAlL5TQFTyUIZDmev0N/bnwqnylEBQS45UKnHx/lUlFvA3fo+jwR8ALb47/oNma38cuqiJ9AAAAAASUVORK5CYII='
file_icon = b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAABU0lEQVQ4y52TzStEURiHn/ecc6XG54JSdlMkNhYWsiILS0lsJaUsLW2Mv8CfIDtr2VtbY4GUEvmIZnKbZsY977Uwt2HcyW1+dTZvt6fn9557BGB+aaNQKBR2ifkbgWR+cX13ubO1svz++niVTA1ArDHDg91UahHFsMxbKWycYsjze4muTsP64vT43v7hSf/A0FgdjQPQWAmco68nB+T+SFSqNUQgcIbN1bn8Z3RwvL22MAvcu8TACFgrpMVZ4aUYcn77BMDkxGgemAGOHIBXxRjBWZMKoCPA2h6qEUSRR2MF6GxUUMUaIUgBCNTnAcm3H2G5YQfgvccYIXAtDH7FoKq/AaqKlbrBj2trFVXfBPAea4SOIIsBeN9kkCwxsNkAqRWy7+B7Z00G3xVc2wZeMSI4S7sVYkSk5Z/4PyBWROqvox3A28PN2cjUwinQC9QyckKALxj4kv2auK0xAAAAAElFTkSuQmCC'

deafult_path = "d:/"

font = ('Courier New', 11)
sg.theme('DarkBlue3')
sg.set_options(font=font)

DIR, FILE = True, False

data = {0: {'kind':DIR, 'path':'', 'file':'C:\', 'children':None}, }
treedata = sg.TreeData()
treedata.insert('', 0, 'C:\', [], icon=folder_icon)

layout = [
    [sg.Tree(treedata, headings=[], col0_width=80, num_rows=20, show_expanded=True, enable_events=True, key='-TREE-')],
    [sg.StatusBar("", size=(0, 1), key='-STATUS-')],
]

window = sg.Window("File Browser", layout, finalize=True)
tree = window['-TREE-']
tree.Widget.configure(show='tree')  # Hide header
tree.bind('<Double-1>', "DOUBLE-CLICK-")
status = window['-STATUS-']
while True:

    event, values = window.read()

    if event == sg.WINDOW_CLOSED:
        break
    status.update('')
    if event == '-TREE-DOUBLE-CLICK-':
        parent_key = values['-TREE-'][0]
        node = data[parent_key]
        if node['kind'] == DIR and node['children'] == None:
            parent_path = Path(node['path']).joinpath(node['file'])
            try:
                files = sorted(list(parent_path.iterdir()), key=lambda file:file.is_file())
            except:
                status.update("Access is denied")
                continue
            node['children'] = []
            for item in files:
                key = new_key()
                kind, path, file = item.is_dir(), str(item.parent), item.name
                treedata.insert(parent_key, key, str(file), [], icon=folder_icon if kind == DIR else file_icon)
                node['children'].append(key)
                data[key] = {'kind':kind, 'path':path, 'file':file, 'children':None}
            tree.update(values=treedata)
            iid = tree.KeyToID[parent_key]
            tree.Widget.see(iid)

window.close()