PySimpleGUI update filepath only when new path is chosen - python

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?

Related

global variable not recognized; says its local variable [duplicate]

This question already has answers here:
UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use)
(14 answers)
Closed 29 days ago.
Its not recognizing the global variable. I experienced this issue before and thought the global variable would prevent the error but no matter what i try it always returns this: local variable 'P1o' referenced before assignment
#import pwinput
import PySimpleGUI as sg
P1o = ("")
P2o = ("")
MAX_ROWS = MAX_COL = 10
def Battleship1():
layout = [
[sg.Text('Player1 please enter your ship positions'), sg.InputText('', size=(10,1), key='input_\P1o')],
[sg.Submit(), sg.Cancel()]
]
window = sg.Window('player1 values', layout)
while True:
event, values = window.read()
if event == sg.WIN_CLOSED:
break
elif event == 'Submit':
P1o = P1o.append(int(values['input_\P1o']))
window.close()
elif event == 'cancel':
window.close()
break
layout = [
[sg.Text('Player2 please enter your ship positions'), sg.InputText('', size=(10,1), key='input_\P2o')],
[sg.Submit(), sg.Cancel()]
]
window = sg.Window('player2 values', layout)
while True:
event, values = window.read()
if event == sg.WIN_CLOSED:
break
if event == 'Submit':
P1o = P1o.append(int(values['input_\P1o']))
turn()
turn_()
if event == 'cancel':
window.close()
break
""" i set up the multiplayer function"""
layout = [ [sg.Text("Welcome to battleship!!\nObject of the game is to sink all five of your enemy's ships!!!\nlabel your ship positions with a number (0-9)\n and another number (0-9)\n and separate each position with spaces e.g 1,2 2,3 3,4")],
[sg.Button('Single Player'), sg.Button('Multiplayer')] ]
window = sg.Window('Menu', layout)
while True:
event, values = window.read()
if event == sg.WIN_CLOSED:
break
if event == 'Multiplayer':
window.close()
Battleship1()
break
I would suggest you to use P1o and P2o as your local variables, as they are only needed in your battleship function.
You can use them as your global or as your local variables. I'll leave the choice to you.
CASE 1: Using it as local variable:
def Battleship1():
P1o = ""
P2o = ""
Here, it just creates two local variables for the function and would prevent the referenced before assignment error.
CASE 2: Using it as global variable:
def Battleship1():
global P1o, P2o
global keyword is used to reference the globals() dictionary where all the global variables are mentioned. So, it would tell the function that P1o and P2o is a global variable.

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()

Force users to select a file with PySimpleGui?

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()

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