Force users to select a file with PySimpleGui? - python

I'm new to PySimpleGui and I've searched every recipe for something that may help me and came up empty handed.
What I'm trying to do is: User will select a file, click a button and the app will do something with the file. This is what I have so far:
layout = [[sg.Text('Sistema'), sg.InputText(key='-file1-'), sg.FileBrowse()], [sg.Button("Go")]]
window = sg.Window('Test', layout)
while True:
event, values = window.read()
if event == "Go":
*do something with file1*
What I want is:
layout = [[sg.Text('Sistema'), sg.InputText(key='-file1-'), sg.FileBrowse()], [sg.Button("Go")]]
window = sg.Window('Test', layout)
while True:
event, values = window.read()
if values["-file1-"] == "":
print("You need to choose a file!")
*allow users to select a new file without closing the window*
if event == "Go":
*do something with file1*
What do I need to do? If I add a break statement, it leaves the while loop and closes the window. I need it to allow users to select a new file and read the window again. Is it possible?

Confirm filename OK or not when event Go in event loop.
Here, Cancel to cancel selection of a file, also stop Go.
from pathlib import Path
import PySimpleGUI as sg
sg.theme("DarkBlue")
layout = [
[sg.Text('Sistema'), sg.InputText(key='-file1-'), sg.FileBrowse()],
[sg.Button("Go")],
]
window = sg.Window('Test', layout)
while True:
event, values = window.read()
if event == sg.WINDOW_CLOSED:
break
elif event == "Go":
filename = values['-file1-']
while True:
if not Path(filename).is_file():
if filename == '':
sg.popup_ok('Select a file to go !')
else:
sg.popup_ok('File not exist !')
filename = sg.popup_get_file("", no_window=True)
if filename == '':
break
window['-file1-'].update(filename)
else:
print('File is ready !')
break
window.close()

Related

PySimpleGUI update filepath only when new path is chosen

I made a GUI with PySimpleGUI where the user has the option to change the standard paths, which will be used in the program. I first defined my standard paths as strings, and then later the user can change them with the help of sg.IN and sg.FolderBrowse fields.
Here the Code:
stdPath1 = "PathToFolder1"
stdPath2 = "PathToFolder2"
layout =
[
[
sg.Text("optional new Path for Folder1:", size=(30, 1)),
sg.In(size=(25, 1), enable_events=True, key='-Folder1-'),
sg.FolderBrowse(),
],
[
sg.Text("optional new Path for Folder2:", size=(30, 1)),
sg.In(size=(25, 1), enable_events=True, key="-Folder2-"),
sg.FolderBrowse()
],
[sg.Button("Start")],
]
window = sg.Window("PrgmName", layout)
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == "Exit":
break
elif event == "Start":
# start Program
elif event == "-Folder1-":
stdPath1 = values[event]+"/"
elif event == "-Folder2-":
stdPath2 = values[event]+"/"
window.close()
This works fine, however sometimes my program returns NONE.
I think this happens when the user clicks the button to choose a new path but closes the Browse window without selecting a new path. Then the event is also triggered, which results in a NONE value being given to my path variable. This of course leads to problems later in the program.
Therefore I would like to only update the FolderPath when a path is actually chosen, not when the button is clicked, but I don't know how to do this.
My only idea would be to add something like "if values[event] is not NONE then pass the new path, otherwise continue to use the stdpath". Is there a better way to do this?

PySimpleGUI Listbox doesn't read first selection?

I'm trying to use a listbox to let user select a movie upon hitting Submit. But the first time the user hits submit, the listbox value is empty. The user has to select and hit Submit a second time for it to work as expected.
def search_window(frame):
names = frame['title']
layout = [[sg.Text("Search for a movie:")],
[sg.Input(size=(50, 1), enable_events=True, key='-INPUT-')],
[sg.Listbox(names, size=(90, 25), key='-LIST-')],
[sg.Submit(key='-SUBMIT-'), sg.Button("Exit")]]
window = sg.Window(title="Movie Search", layout=layout, size=(600, 400))
while True:
event, values = window.read()
if event == "Exit" or event == sg.WIN_CLOSED:
break
if values['-INPUT-'] != '':
search = values['-INPUT-']
search_lower = [x.lower() for x in search]
search_lower = ''.join(search_lower)
new_values = [x for x in names if search_lower in x.lower()]
window['-LIST-'].update(new_values)
else:
window['-LIST-'].update(names)
if event == '-SUBMIT-':
global movie
movie = values['-LIST-']
movie = ''.join(movie)
sg.popup(movie, ' Selected as Movie')
window.close()
Image attached for when the user first selects from the list and hits Submit-
If I take out the re-casting from list to string, that does not help. I also tried moving the if block above the if/else for searching; that caused it to instead pick a random movie from the list instead of an empty result.
I'm very new to PySimpleGUI, so apologies if this is easy :)

PySimpleGui can not access list in InputCombo

I am making a simple gui for my python script with PySimpleGui and enterd a problem. Everytime i want to add a new integer to my InputCombo list, I can not access the new integer.
I wrote a basic script to show:
import PySimpleGUI as sg
things=["a","b"]
layout=[[sg.Input(key="-input-",size=(10,1)),sg.Button("add",key="-add-")],
[sg.InputCombo(things,key="-combo-"),sg.Button("write")],
[sg.Text("",key="-output-"),sg.Button("Quit")]]
window=sg.Window("Name",layout,size=(200,200))
while True:
event,values=window.read()
if event==sg.WINDOW_CLOSED or event=="Quit":
break
if event=="add":
things.append(values["-input"])
if event=="write":
window["-output-"].update(values["-combo-"])
I have a list "things". I can add a new value, if I write something in the inputfield. WIth the Button "add" i add the value to my list "things". With the InputCombo I can access the vvalues in my list, for example "a" and "b". If I choose "a" or "b" an press "write", the Textfield will update and write "a" or "b". But in the InputCombo I can n ot choose values, which I have added later.
Does anybody have an idea how I can get things working?
Call method update(values=things) of sg.InputCombo to update new values.
Revised code,
import PySimpleGUI as sg
things = ["a","b"]
layout = [
[sg.Input(key="-input-", size=(10,1)),
sg.Button("add", key="-add-")],
[sg.InputCombo(things, key="-combo-"),
sg.Button("write")],
[sg.Text("", key="-output-"),
sg.Button("Quit")],
]
window = sg.Window("Name", layout, size=(200, 200))
while True:
event, values = window.read()
if event == sg.WINDOW_CLOSED or event == "Quit":
break
elif event == "-add-": # Correct event to add
things.append(values["-input-"])
window['-combo-'].update(values=things) # Statement to update
elif event == "write":
window["-output-"].update(values["-combo-"])
window.close()

I'm getting an error trying to save values of a Multiline(key='-OUT-'). pysimplegui

while True:
event, values = window.read()
if event == "Exit" or event == sg.WIN_CLOSED:
break
if event == 'Open Ctrl-O':
try:
filename = sg.popup_get_file('Open',file_types=(('Text','*.txt*'),), no_window=True)
openfile = open(filename,'r')
window['-IN-'].update(openfile.read())
except:
window.read()
elif event == 'Browse':
try:
filename = sg.popup_get_file('Open',file_types=(('Text','*.txt*'),), no_window=True)
openfile = open(filename,'r')
window['-IN-'].update(openfile.read())
except:
window.read()
elif event == 'Clear':
window['-IN-'].update('')
elif event == "-Submit-":
layout2 = [[sg.Menu(menu_def, tearoff=False, key='-MENU-')],
[sg.Multiline(size=(125,40), key='-OUT-', auto_refresh= True, font=('Consolas',10), reroute_stdout= True)],
[sg.Button('Save As', file_types=(('Text','*.txt*'),),
default_extension='.txt', enable_events=True, key='save')]]
window2 = sg.Window('TabNotes', layout2, margins=(10,10),location=(600,90), finalize=True)
window2['-OUT-'].update(new_input())
while True:
event, value = window2.read()
if event == "Exit" or event == sg.WIN_CLOSED:
break
elif event == 'Clear':
window2['-OUT-'].update('')
elif event == 'save':
newfile=values['-OUT-']
try:
filename = sg.popup_get_file('Save', default_extension = '.txt', save_as=True,
file_types=(('Text','*.txt*'),), no_window=True)
savefile = open(filename, 'w')
savefile.write(newfile)
savefile.close()
except:
window2.read()
window2.close()
window.close()
This results in:
Keyword Error: '-OUT-'
#########
The program takes an input in window(), and then when I click submit, it will take the input and run it through a function where it changes the input with respect to certain characters. E.G: if the input was " 1 2 3", the output in window2 will be " A B C "
Now I want to save the file with the "A B C" but I'm running into this error.

Python - SimpleGui - Listbox - After Search I lose the highlight

I've a very simple interface where I have a listbox with my employee names and a Input text where I can put the name to search more quickly.
I've I don't put any text on the input I can select the employee name with a highlight like this:
But if I search for the name (and then I will update this element for the new list with only the names that contains the text that I write) I am not able to get the highlight, as you can see:
My code:
import PySimpleGUI as sg
employees_list = ['John','Pete','Anne','Jack','Golsing']
layout = [[sg.Input(visible=True,size=(15, 1), enable_events=True,key='-input-')]
,[sg.Listbox(values=employees_list,size=(15, 3),enable_events=True, select_mode=sg.LISTBOX_SELECT_MODE_MULTIPLE, key='-employee-')]]
Window = sg.Window('DEV', layout)
while True:
Event, Values = Window.read()
if Event == sg.WIN_CLOSED:
break
if Values['-input-'] != '':
search = Values['-input-'].upper()
new_employees = [x.upper() for x in employees_list if search in x]
Window.Element('-employee-').Update(values=new_employees, select_mode=sg.LISTBOX_SELECT_MODE_MULTIPLE)
Has anyone been through this? How can I solve it?
Thanks!
You should handle different event here,
if Values['-input-'] != '':
Here, you will do it if any event generated, so Listbox will be updated when you click Listbox, so selection will be set to none, that's why no item selected or highlighted.
So the code should be
if Event == '-input-' and Values['-input-'] != '':
And here you don't recover the listbox to full list when empty input. So maybe you need to handle another case for
if Event == '-input-' and Values['-input-'] == '':
# update Listbox with values=employees_list

Categories