Is there a way to either choose one file in a folder or multiple files in a folder or just a folder (and then process all the files inside it) with PySimpleGUI? So far I've made something like this:
import PySimpleGUI as sg layout = [[sg.Text("Select files or folder:", sg.Input(key='-IN1-'),sg.FilesBrowse('Select')], [sg.Button("Ok"),sg.Button("Cancel")]] window = sg.Window("Test_window", layout) ...
But with this code I can only choose one or multiple files in a folder, and cannot choose a folder. I want a way to choose either one file, multiple files or a folder.
12 Answers
You can select a folder, but not both a folder or files. Here is how to select a folder:
left_col = [[sg.Text('Folder'), sg.In(size=(25,1), enable_events=True ,key='-FOLDER-'), sg.FolderBrowse()]] layout = [[sg.Column(left_col, element_justification='c')] window = sg.Window('Multiple Format Image Viewer', layout,resizable=True) while True: event, values = window.read() if event in (sg.WIN_CLOSED, 'Exit'): break if event == '-FOLDER-': folder = values['-FOLDER-']
This may not the best suggestion, but you could have two buttons [Files] [Folder] and let them select one or the other, would that work?
I faced a similar (perhaps the same) problem on an app that queues up music tracks: you want to be able to choose individual tracks and/or whole albums. I tried the two-buttons approach, but an artists/albums/tracks tree is a mile wide and an inch deep, so using the standard browse popups is awful.
I started with PSG's Tree demo. I added a few lines to their add_files_in_folder function because the dirlist result isn't sorted. This makes a people-friendly tree:
if files is None: print(f"got None from os.listdir({dirname})") files = [] if len(files) > 1: files = sorted(files)
The popup is called from a parent window that has a listbox where tracks accumulate. It passes the root directory of the music collection, the listbox object, the offset in the listbox contents where new tracks should be inserted, and a dict that has items from the settings file (make sure you have something valid for "tree_wloc": TKInter throws exceptions if you give it None). The type_filter() function does the usual filename.lower().endswith() screening, if you need it.
This code kinda "cheats" because it uses two TKInter methods that PSG doesn't encapsulate to access the Treeview selections. If you're using PSG on a system where it's not built on TKInter. you may have to find different methods or discover this kluge can't be used.
Something some might consider a flaw: selecting a folder effectively selects its contents, but they aren't highlighted. It should be possible to change that, but it would require doing more kluging with TKInter internals. And I think the mental model of "selecting an album" vs "selecting tracks" works, so I expect to stick with it.
def popup_add_tracks(starting_path, field, ip, settings): theme=settings.get("tree_theme") wloc=settings.get("tree_wloc") treefont=settings.get("tree_font") treedata = sg.TreeData() playlist = [] type_masks = [".ogg", ".mp3", ".flac"] if not starting_path or not os.path.isdir(starting_path): return [] playlist = [] if theme == None : theme='BlueMono' sg.theme(theme) if wloc == None : wloc=(None,None) add_files_in_folder('', starting_path, type_masks, treedata) layout = [[sg.Text('Select tracks and/or albums to add to the playlist', font=treefont)], [sg.Text('Click "Add to list" to add them', font=treefont)], [sg.Text("Click \"Ok\" when you're finished ", font=treefont)], [sg.Tree(data=treedata, headings=['Size', ], auto_size_columns=True, select_mode=sg.TABLE_SELECT_MODE_EXTENDED, num_rows=20, col0_width=60, font=treefont, key='-TREE-', show_expanded=False, enable_events=True, expand_x=True, expand_y=True, ),], [sg.Button('Ok'), sg.Button('Add to list', k="-ADD-")]] window = sg.Window('Tree Element Test', layout, resizable=True, finalize=True, location=wloc) while True: # Event Loop event, values = window.read() if event == sg.WIN_CLOSED: retval = False break #print(event, values) if event == 'Ok': retval = True break if event == '-TREE-': last_selected = window['-TREE-'].TKTreeview.selection() last_items = values['-TREE-'] #print(event, values) #print(delected) if event == '-ADD-': add_files_to_playlist(playlist, last_items, type_masks) if len(playlist): prev_list = field.get_list_values() new_list = prev_list[:ip] + playlist + prev_list[ip:] field.Update(new_list) ip += len(playlist) playlist = [] for i in last_selected: window['-TREE-'].TKTreeview.selection_remove(i) settings['tree_wloc'] = window.current_location() window.close() return retval
ncG1vNJzZmirpJawrLvVnqmfpJ%2Bse6S7zGiorp2jqbawutJobW9rY2yDcYSOn6ClnaNivLN5xaijnZ2iYq%2Bzu9asnGahnmK9ur%2FIpqelnZeqtg%3D%3D