如何在 PySimpleGUI 中使用嵌套事件

How to use nested events in PySimpleGUI

我正在尝试使用嵌套事件。 当我浏览文件时,单独从完整路径中剥离的文件名会触发一个事件,该事件使文件名被传输到 enable_events 设置为 true 的文本框,这将触发另一个事件来调用函数和获取 pdf 详细信息。

如果我启用两条注释行,您可以看到该函数有效并传输 return 值,但我试图将这两个事件分开作为获取 PDF 详细信息的函数需要一段时间。

所以顺序是:

__pdfpath__ 获取某个浏览文件的完整路径,触发一个将文件名传输到 __bookfilename__[= 的事件34=] 这应该触发另一个事件,该事件将调用一个函数,该函数将其响应发送到 __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)

那么问题来了,如何触发第二个事件?

我尝试创建第二个 window.Read() 来创建第二个循环,如下所示:

event2, value2 = window.Read()

但没用。

有什么想法吗?

谢谢

解决这个问题的方法不是围绕 PySimpleGUI 的事件。您需要做的是将 long-running 函数分解为线程。

编辑 - 自 2019 年初的原始答案以来,许多内容继续添加到 PySimpleGUI 中。

由于函数运行时间过长是编写 GUI 时最常遇到的问题之一,因此添加了一种方法,以便尚未准备好编写自己的线程代码的初学者不会受到阻碍。

Window.perform_long_operation 将一个函数或 lambda 表达式作为参数和一个键,该键将在您的函数 returns.

时返回
window.perform_long_operation(my_long_operation, '-OPERATION DONE-')

您将获得 multi-threading 的好处,而无需自己完成所有工作。这是一个“踏脚石”的方法。有些用户在编写他们的第一个 GUI 时才使用 Python 2 或 3 周,根本没有准备好使用线程模块。

Cookbook 中有一节是关于这个主题的,eCookbook 中有许多示例,可以立即 运行。 http://Cookbook.PySimpleGUI.org and http://Cookbook.PySimpleGUI.org

演示程序始终是查看的好地方 - http://Demos.PySimpleGUI.org。截至 2021 年,那里至少显示了 13 个示例。

试试这个:

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)

PSG有一个魔法元素可以随时触发事件,基本上就是Button,可以通过设置visible=False来隐藏。只需在您想触发 'ButtonKey' 事件的地方调用 window['ButtonKey'].click()