鱼C论坛

 找回密码
 立即注册
查看: 1844|回复: 9

[已解决]PySimpleGUI窗口运行时间有点久,如何优化?

[复制链接]
发表于 2023-8-3 15:12:26 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
代码如下,如果没有for循环,窗口很快会关闭。有了循环,窗口貌似是等循环结束后才关闭。
请问有没有办法让窗口在获取完信息之后马上关闭,或者尽快关闭呢?非常感谢!
import PySimpleGUI as sg
layout=[
    [sg.T('月份:'), sg.In('2023-05')],
    [sg.T('路径1:'),sg.FolderBrowse()],
    [sg.T('路径2:'), sg.FolderBrowse()],
    [sg.B('确认'), sg.B('取消')]
]
window = sg.Window('核对', layout, keep_on_top=True)
while 1==1:
    event,value=window.read()
    if event in (None, '取消'):
        break
    if event =='确认':
        month = value[0]
        p_backend = value['Browse']
        p_erp = value['Browse0']
        break
for i in range(10000000000):
    a=1
print(month)
print(p_backend)
print(p_erp)
最佳答案
2023-8-3 15:12:44
在PySimpleGUI中,窗口的关闭是基于事件驱动的,默认情况下窗口会等待所有的事件处理完毕才会关闭。所以如果有一个耗时很长的循环,窗口就会在循环结束后才关闭。

要优化这个问题,可以考虑将耗时的操作放在子线程中执行,这样主线程就可以继续响应其他事件,包括关闭窗口事件。下面是修改后的代码示例:
import PySimpleGUI as sgimport threadingdef long_running_task():    for i in range(10000000000):        a = 1layout = [    [sg.T('月份:'), sg.In('2023-05')],    [sg.T('路径1:'), sg.FolderBrowse()],    [sg.T('路径2:'), sg.FolderBrowse()],    [sg.B('确认'), sg.B('取消')]]window = sg.Window('核对', layout, keep_on_top=True)while True:    event, value = window.read()    if event in (None, '取消'):        break    if event == '确认':        month = value[0]        p_backend = value[1]        p_erp = value[2]                # 创建子线程执行耗时操作        thread = threading.Thread(target=long_running_task)        thread.start()        break    # 持续更新窗口,确保用户操作的响应    window.refresh()window.close()print(month)print(p_backend)print(p_erp)
在上面的示例代码中,我将耗时操作 long_running_task() 放在了一个子线程中执行,这样主线程就可以继续处理其他事件。同时,我添加了 window.refresh() 方法来持续更新窗口,确保用户操作的响应。这样,在确认按钮被点击后,窗口会立即关闭。

希望这个优化方法对你有帮助!如有任何问题,请随时提问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-8-3 15:12:44 | 显示全部楼层    本楼为最佳答案   
在PySimpleGUI中,窗口的关闭是基于事件驱动的,默认情况下窗口会等待所有的事件处理完毕才会关闭。所以如果有一个耗时很长的循环,窗口就会在循环结束后才关闭。

要优化这个问题,可以考虑将耗时的操作放在子线程中执行,这样主线程就可以继续响应其他事件,包括关闭窗口事件。下面是修改后的代码示例:
import PySimpleGUI as sgimport threadingdef long_running_task():    for i in range(10000000000):        a = 1layout = [    [sg.T('月份:'), sg.In('2023-05')],    [sg.T('路径1:'), sg.FolderBrowse()],    [sg.T('路径2:'), sg.FolderBrowse()],    [sg.B('确认'), sg.B('取消')]]window = sg.Window('核对', layout, keep_on_top=True)while True:    event, value = window.read()    if event in (None, '取消'):        break    if event == '确认':        month = value[0]        p_backend = value[1]        p_erp = value[2]                # 创建子线程执行耗时操作        thread = threading.Thread(target=long_running_task)        thread.start()        break    # 持续更新窗口,确保用户操作的响应    window.refresh()window.close()print(month)print(p_backend)print(p_erp)
在上面的示例代码中,我将耗时操作 long_running_task() 放在了一个子线程中执行,这样主线程就可以继续处理其他事件。同时,我添加了 window.refresh() 方法来持续更新窗口,确保用户操作的响应。这样,在确认按钮被点击后,窗口会立即关闭。

希望这个优化方法对你有帮助!如有任何问题,请随时提问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-8-3 15:12:47 | 显示全部楼层
你好!这个问题的根本原因是因为你的程序在执行完  for  循环之前不会继续执行窗口的事件循环,因此窗口只能在循环结束后才能响应关闭事件。为了解决这个问题,你可以通过在  for  循环中使用多线程来使窗口能够及时响应关闭事件。

下面是你的代码的优化版本,使用了多线程来处理  for  循环,从而使窗口能够在后台进行事件循环,同时你的计算也可以在另一个线程中执行,这样窗口就能够在获取完信息后立即关闭:
import PySimpleGUI as sg
import threading

def long_running_task():
    for i in range(10000000000):
        a = 1
    print(month)
    print(p_backend)
    print(p_erp)

layout = [
    [sg.T('月份:'), sg.In('2023-05')],
    [sg.T('路径1:'), sg.FolderBrowse()],
    [sg.T('路径2:'), sg.FolderBrowse()],
    [sg.B('确认'), sg.B('取消')]
]

window = sg.Window('核对', layout, keep_on_top=True)

while True:
    event, value = window.read()
    
    if event in (None, '取消'):
        break
    if event == '确认':
        month = value[0]
        p_backend = value['Browse']
        p_erp = value['Browse0']
        
        # 创建一个线程来执行耗时的任务
        task_thread = threading.Thread(target=long_running_task)
        task_thread.start()
        
        break

window.close()

这段代码创建了一个新的线程  task_thread  来执行  for  循环,从而不会阻塞主线程中的 PySimpleGUI 事件循环。这样一来,窗口就能够在获取完信息后立即关闭,而不需要等待  for  循环的完成。记得要导入  threading  模块,以便使用多线程功能。

希望这可以解决你的问题!如果你有任何疑问,请随时问我。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-8-3 15:12:50 | 显示全部楼层
在你的代码中,窗口运行时间久的原因是因为你的循环在执行的过程中阻塞了窗口的事件处理,导致窗口无法及时响应关闭事件。为了优化窗口的关闭速度,你可以采取以下方法:

1. 将长时间执行的任务放在后台线程中进行:可以使用threading模块将长时间执行的任务放在一个独立的线程中运行,这样窗口就可以在主线程中继续响应事件和关闭。示例代码如下:
import threadingimport PySimpleGUI as sgdef long_running_task():    for i in range(10000000000):        a = 1layout = [            [sg.T('月份:'), sg.In('2023-05')],            [sg.T('路径1:'), sg.FolderBrowse()],            [sg.T('路径2:'), sg.FolderBrowse()],            [sg.B('确认'), sg.B('取消')]         ]window = sg.Window('核对', layout, keep_on_top=True)while True:    event, value = window.read()        if event in (None, '取消'):        break        if event == '确认':        month = value[0]        p_backend = value['Browse']        p_erp = value['Browse0']                # 在后台线程中执行长时间任务        thread = threading.Thread(target=long_running_task)        thread.start()        breakwindow.close()
2. 使用window.finalize()方法尽快显示窗口并释放控制权:在你的代码中,调用window.finalize()方法可以尽快显示窗口并释放控制权,以便让窗口能够响应关闭事件。示例修改代码如下:
import PySimpleGUI as sglayout = [            [sg.T('月份:'), sg.In('2023-05')],            [sg.T('路径1:'), sg.FolderBrowse()],            [sg.T('路径2:'), sg.FolderBrowse()],            [sg.B('确认'), sg.B('取消')]         ]window = sg.Window('核对', layout, keep_on_top=True)window.finalize()  # 尽快显示窗口并释放控制权while True:    event, value = window.read()        if event in (None, '取消'):        break        if event == '确认':        month = value[0]        p_backend = value['Browse']        p_erp = value['Browse0']                for i in range(10000000000):            a = 1        breakwindow.close()
通过上述优化方式,你可以提高窗口的响应速度和关闭速度。希望对你有帮助!如果还有其他问题,请随时提问。

如果回答对你有帮助,请给我一个最佳答案!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2023-8-3 15:17:05 | 显示全部楼层
给我最佳答案呗!求你了!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 0 反对 1

使用道具 举报

发表于 2023-8-3 15:18:44 | 显示全部楼层
对于楼上这种不要脸行为,尽量不要给最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-8-3 15:20:43 | 显示全部楼层
Mike_python小 发表于 2023-8-3 15:18
对于楼上这种不要脸行为,尽量不要给最佳答案

哈哈哈哈哈哈哈哈哈哈
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-8-3 15:23:40 | 显示全部楼层
isdkz 发表于 2023-8-3 15:12
你好!这个问题的根本原因是因为你的程序在执行完  for  循环之前不会继续执行窗口的事件循环,因此窗口只 ...

谢谢你的解答,因为大家答案都一样,所以最佳我给了最快回复的人
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-8-3 15:24:16 | 显示全部楼层
学习编程中的Ben 发表于 2023-8-3 15:12
在你的代码中,窗口运行时间久的原因是因为你的循环在执行的过程中阻塞了窗口的事件处理,导致窗口无法及时 ...

谢谢你的解答,因为大家答案都一样,所以最佳我给了最快回复的人
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-8-3 15:55:09 | 显示全部楼层
发现按照大家的回复运行之后,发现把多线程放在while循环里面,并没有快速关闭窗口。需要把多线程放在while循环外,window.close()之后。
而且,原来是我漏写了window.close(),写上就可以到达要求了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-25 20:57

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表