-1

I am brand new with PySimpleGUI but it's turning out to be really easy as advertised. After just a couple of hours I already have a halfway-working application.

I'm using a Listbox to display several rows of items read in from a disk file. When I click my Show Connections button it reads the file and displays the items like I want. But if I click the button again, it reads the file again and now I have two copies in the box. I want to empty out the listbox before it gets updated from the next disk file read so that it always shows just exactly what is in the file. I have tried Update and set_value but can't seem to get anything to work.

layout_showdata = [
    [
    sg.Text('Time',size=(10,1)),
    sg.Text('Destination',size=(14,1)),
    sg.Text('Source',size=(14,1))],
    [sg.Listbox(size=(38,10),values=[''],key='_display_')]
]

. . .

    if event == 'Show Connections':
        print('Show Connections')
        window['panel_show'].update(visible=True)
        window['panel_edit'].update(visible=False)
        window['panel_entry'].update(visible=False)
        window['_display_'].set_value([])      ***#<==This should do it I thought***
        with open('connections.txt','r') as cfile:
            schedule=csv.reader(cfile,dialect="pipes")
            for row in schedule:
                items.append(row[0]+':'+row[1]+':'+row[2]+' '+row[3]+'   '+row[4])
                print(items[itemnum])
                itemnum+=1
            window.FindElement('_display_').Update(items)

I'm sure I'm missing something simple and would appreciate whatever help I can get.

[EDIT] Added some running code to illustrate what happens. Instead of the listbox clearing when the button is pushed, it just reads the file again and adds to what is already there:

import PySimpleGUI as sg
import csv
items = []
itemnum = 0
csv.register_dialect('pipes', delimiter='|')

file = [
'01|23|45|12345678|87654321',
'04|35|23|24680864|08642468',
'01|23|45|12345678|87654321',
'04|35|23|24680864|08642468',
'01|23|45|12345678|87654321',
'23|23|23|12341234|43214321'
]


layout_showdata = [
        [
        sg.Text('Time',size=(10,1)),
        sg.Text('Destination',size=(14,1)),
        sg.Text('Source',size=(14,1))],
        [sg.Listbox(size=(38,10),values=[''],key='_display_')],
        [sg.Button('Show Connections')]
    ]
window = sg.Window('XY Scheduler', layout_showdata)

while True:
    event, values = window.Read(timeout=1)
    if event in (None, 'Quit'):
        break

#Show Existing Connections
    
    if event == 'Show Connections':
        print('Show Connections')
        window['_display_'].update([])
        schedule=csv.reader(file,dialect="pipes")
        for row in schedule:
            items.append(row[0]+':'+row[1]+':'+row[2]+'         '+row[3]+'              '+row[4])
            print(items[itemnum])
            itemnum+=1
        window.FindElement('_display_').Update(items)

1 Answers1

0

You want the update method if you want to change the values. You'll find it has a values parameter. The call reference document or docstrings will help you quite a bit, but the general rule of thumb to use is that update is the method to change something about an element.

You had already been calling it for the other elements. You just needed to call it for the listbox.

window['_display_'].update([]) 

The set_values call has this description in the docs: "Set listbox highlighted choices"

It sets what has been selected, not the choices you have to select.

[EDIT] Here is a full example of how to remove all entries in a listbox. Maybe I'm misunderstanding the question.

import PySimpleGUI as sg

def main():
    layout = [  [sg.Text('My Window')],
                [sg.Listbox([1,2,3,4,5], size=(5,3), k='-LB-')],
                [sg.Button('Go'), sg.Button('Exit')]  ]

    window = sg.Window('Window Title', layout)

    while True:             # Event Loop
        event, values = window.read()
        print(event, values)
        if event == sg.WIN_CLOSED or event == 'Exit':
            break
        if event == 'Go':
            window['-LB-'].update([])
    window.close()

if __name__ == '__main__':
    main()
Mike from PSG
  • 5,312
  • 21
  • 39
  • After I posted the question I realized that set_values was wrong. But I had already tried using update and it didn't work. Just tried it again to be sure and the behavior is the same. It seems to ignore the update and just reloads the lines from the file and adds them to those already in the listbox. Added some code to original post to illustrate. Thanks @MikeyB and anyone else who can help. – swalker2001 Nov 25 '20 at 14:46
  • Print what you're passing to update to make sure you're sending what you think you are. Added a full example for you. If you change the [] into a list [4,5,6], you'll see that the listbox changes to those values. I don't think this is a PySimpleGUI problem. – Mike from PSG Nov 25 '20 at 15:16
  • Look at the logic in your code. The only operation you perform on `items` inside your event loop is `items.append`. The reason your listbox adds the new things to hose already in the listbox is because that's what your code is doing. It's not a PySimpleGUI problem... it's a logic problem in your code. Print `items` that you're passing to the `update` method and you'll see that you're passing in bad information. ‍♂️ – Mike from PSG Nov 25 '20 at 19:24
  • Yes, that was it. I knew it was something dumb. I was hyper-focused on PySimpleGUI being the issue and missed my own mistake. Thanks! – swalker2001 Nov 25 '20 at 23:20
  • Care to maybe mark the answer as correct so the next person sees it? – Mike from PSG Nov 26 '20 at 19:19