PySimpleGui 树添加带有事件的元素以减少启动时间
PySimpleGui Tree Add Elements with an Event to Reduce Startup Time
我正在尝试将 GUI 添加到我制作的命令行程序中。我需要一个文件树到 select 个程序文件。我找到了一个使用 PySimpleGUI 的程序,但它需要一段时间才能启动,因为它必须递归地遍历文件。
我能够通过限制递归深度并在插入 TreeData 后使用 update(values=treedata)
来解决这个问题。这虽然会重置树(关闭所有打开的展开文件夹)并且是一种糟糕的用户体验。
update
函数还允许您使用 key
和 value
修改节点,但是您可以添加节点并定义它们的父节点吗?我好像找不到 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()
我正在尝试将 GUI 添加到我制作的命令行程序中。我需要一个文件树到 select 个程序文件。我找到了一个使用 PySimpleGUI 的程序,但它需要一段时间才能启动,因为它必须递归地遍历文件。
我能够通过限制递归深度并在插入 TreeData 后使用 update(values=treedata)
来解决这个问题。这虽然会重置树(关闭所有打开的展开文件夹)并且是一种糟糕的用户体验。
update
函数还允许您使用 key
和 value
修改节点,但是您可以添加节点并定义它们的父节点吗?我好像找不到 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()