PySimpleGUI Listbox doesn't read first selection? - python

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

Related

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

Pause a for loop to wait for a button press

I am trying to build an image classifier and I need to manually assign classifications for a training dataset, so I build a file browser /media window app in tkinter to display images and assign them classifications via a button click. To iterate over the files, I am using a for loop, but I need it to pause and wait for that input. Here is my code:
def setKnownData(self):
training_sample = self.dataset.sample(frac = .1)
print(training_sample)
for i, row in training_sample.iterrows():
print(row)
global img
file = Image.open(row['ID'])
resized = file.resize((500,600))
img = ImageTk.PhotoImage(resized)
self.media_window.create_image(0,0, anchor = 'nw', image = img)
self.event_var.get()
while True:
if self.event_var.get() == 0:
print(self.event_var.get())
return
if self.event_var.get() == 1:
training_sample.loc[row]['class'] = 'cartoon'
break
elif self.event_var.get() ==2:
training_sample.loc[row]['class'] = 'photo'
break
self.event_var.set(0)
def stateSwitch(self, action):
print('state switching....')
if action == 'toon':
print(self.event_var.get())
self.event_var.set(1)
print('classification: TOON', self.event_var.get())
elif action == 'photo':
self.event_var.set(2)
print('classification: PHOTO')
I've exausted every combination of IntVar, tkinter, and for loop searches and can't find a viable solution, so I apologize if this is a repeat question. How can I pause this for loop, wait for a putton press, and then proceed to the next image in the list?
You need to shift your thinking away from pausing the loop. That's procedural programming, but GUIs are work much better as "event driven programming", where the entire program is just endlessly waiting for an event (like a button press) to happen. The means no loops, besides the tkinter mainloop. And it means making a new function for every event.
def setKnownData(self):
training_sample = self.dataset.sample(frac = .1)
print(training_sample)
self.training_sample = training_sample.iterrows()
def on_button_click(self):
i, row = next(self.training_sample)
print(row)
global img
file = Image.open(row['ID'])
resized = file.resize((500,600))
img = ImageTk.PhotoImage(resized)
self.media_window.create_image(0,0, anchor = 'nw', image = img)
self.event_var.get()
while True:
if self.event_var.get() == 0:
print(self.event_var.get())
return
if self.event_var.get() == 1:
training_sample.loc[row]['class'] = 'cartoon'
break
elif self.event_var.get() ==2:
training_sample.loc[row]['class'] = 'photo'
break
self.event_var.set(0)

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

After inputting a value in QLineEdit(), I want to display only the rows in QTableWidget by pressing the search button

When you entered a value in the edit window created by the QLineEdit() function, and then clicked QPushButton, you tried to print only the rows that matched the values ​​entered in the edit window. If you press the search button without entering anything, you want to see all the results (rows) again.
I used setRowHidden() to do this, but I do not see the above results.
Is there a function that provides the above functions? I would like to know if there is a solution.
I tried changing the argument value of setRowHidden() to True or False, but I could not get the desired result.
def OnFilter(self):
for i in range(0, tableWidget.rowCount()):
item = tableWidget.item(i, 1)
if (item is not None and item.data(QtCore.Qt.EditRole) == (self.SearchEdit.text())):
tableWidget.setRowHidden(i, False)
else:
tableWidget.setRowHidden(i, True)
self.SearchEdit = QLineEdit()
self.SearchButton = QPushButton("search")
self.SearchButton.clicked.connect(self.OnFilter)
If you press the search button after entering the value in the current edit window, only the corresponding line is output. However, if you try to view the entire value (row) by clearing the value entered in the edit window and pressing the search button, nothing will be output.
You are saying that when self.SearchEdit.text() == "" all rows should be shown, but your code treats an empty string ("") same as a keyword and tries to match it in your table.
Put an if statement in your function so that if self.SearchEdit.text() == "", all rows are displayed. You can do like this:
def OnFilter(self):
if self.SearchEdit.text() == "":
for i in range(0, tableWidget.rowCount()):
tableWidget.setRowHidden(i, False)
return
for i in range(0, tableWidget.rowCount()):
item = tableWidget.item(i, 1)
if (item is not None and item.data(QtCore.Qt.EditRole) ==
(self.SearchEdit.text())):
tableWidget.setRowHidden(i, False)
else:
tableWidget.setRowHidden(i, True)

Categories