user1709612
user1709612

Reputation:

How to use nested events in PySimpleGUI

I'm trying to used nested events. When I browse a file, the filename alone being stripped from the full path triggers an event that makes the filename to be transferred to a textbox which has the enable_events set to true, which will trigger another event to call a function and get the pdf details.

If I enable the two commented lines, you can see that the function works and transfers the return value, but I'm trying to separate these two events as the function to get the details of the PDF takes a while.

So the order is:

__pdfpath__ gets the full path of a certain browsed file which triggers an event that transfers the filename to __bookfilename__ which should trigger another event which will call a function that will send its response to __pdfdetails__

import PySimpleGUI as sg
import os


def get_pdf_details(pdfname):

    return pdfname + ' was processed'

layout = [

[sg.InputText('',key='_pdfpath_',enable_events=True),sg.FileBrowse(key='_filepath_')],
[sg.Text('',key='_bookfilename_',enable_events=True,size=(40, 1))],
[sg.Text('',key='_pdfdetails_', size=(40, 1) )],


]

window = sg.Window('', layout)

while True:
    event, value = window.Read()

    if event == '_pdfpath_':
        filename = os.path.basename(value['_pdfpath_'])
        window.Element('_bookfilename_').Update(filename)

        #response = get_pdf_details(filename)
        #window.Element('_pdfdetails_').Update(response)
    if event == '_bookfilename_':
        response = get_pdfdetails(value['_bookfilename_'])
        window.Element('_pdfdetails_').Update(response)

So the question is, how can I trigger the second event?

I tried creating a second window.Read() to create a second loop like this:

event2, value2 = window.Read()

but didn't work.

Any ideas?

Thanks

Upvotes: 1

Views: 5977

Answers (3)

Mike from PSG
Mike from PSG

Reputation: 5764

The way through this isn't events traveling around PySimpleGUI. What you need to do is break out your long-running function into a Thread.

EDIT - Since the original answer in early 2019 a lot of continued to be added to PySimpleGUI.

Because having a function take too long be one of the most common problems first encountered writing a GUI, a method was added so that beginners that are not quite ready to write their own threaded code aren't held up.

The Window.perform_long_operation takes a function or a lambda expression as a parameter and a key that will be returned when your function returns.

window.perform_long_operation(my_long_operation, '-OPERATION DONE-')

You'll get the benefits of multi-threading without needing to do all the work yourself. It's a "stepping stone" approach. Some users have only been using Python for 2 or 3 weeks when they write their first GUI and simply aren't ready for the threading module.

The Cookbook has a section on this topic and the eCookbook has a number of examples that can be immediately run. http://Cookbook.PySimpleGUI.org and http://Cookbook.PySimpleGUI.org

The Demo Programs are always a great place to look too - http://Demos.PySimpleGUI.org. There are at least 13 examples shown there as of 2021.

enter image description here

Upvotes: 1

K. Tewa
K. Tewa

Reputation: 1

PSG has one magic element that can Fire event whenever you want, It's basically is Button, it can be hidden by setting visible=False. Just call window['ButtonKey'].click() where you want to fire 'ButtonKey' event.

Upvotes: 0

albar
albar

Reputation: 3100

Try this:

while True:
    event, value = window.Read()
    process_event(event, value)
def process_event(event, value):
    if event == '_pdfpath_':
        filename = os.path.basename(value['_pdfpath_'])
        window.Element('_bookfilename_').Update(filename)
        value.update(_bookfilename_=filename)
        process_event('_bookfilename_', value)
    if event == '_bookfilename_':
        response = get_pdfdetails(value['_bookfilename_'])
        window.Element('_pdfdetails_').Update(response)

Upvotes: 0

Related Questions