使用 PySimpleGUI 创建自定义进度条
Using PySimpleGUI to create a custom progress bar
我刚开始学习 PySimpleGUI,我想创建一个自定义 GUI 进度条,它将在不同时间显示程序的哪些部分 运行。
例如,我有一个包含各种组件的视频处理程序,所以我希望进度条显示如下文本:
'Extracting Frame 1 from Video'
'Cropping images'
'Removing Duplicate Images'
但是所有这些行都需要从程序中的不同函数更新进度条 window,其中与包含进度条的 window 关联的 GUI 代码不是 运行。
我的代码:
image_name_list = Frame_Capture(f"{main_dir}\{input_line2}.mp4") # Generates image list of frames of video
Remove_Duplicates(image_name_list) # Removes duplicate images
print("Enter name of pdf file")
pdf_name = f'{input()}.pdf'
makePdf(pdf_name, image_name_list) # Converts images to pdf
Cleanup(image_name_list) # Deletes unneeded images
os.startfile(pdf_name)
在这里,当我的程序本身的 GUI 组件时,我需要从 'Frame_Capture'、'Remove_Duplicates'、'makePDF' 和 'Cleanup' 函数中更新 GUI Process 栏运行 在程序的另一部分。
我能想到的两种方案是:
- 全局创建我的 window 并全局更新其中的进度条
- 当我的程序到达需要更新进度条的部分时,将我所有的进度条语句逐行写入一个文本文件,同时每隔几毫秒将文本文件中的最新语句加载到我的进度条中。
这些解决方案听起来都不好。我还有其他方法可以做到这一点吗?
为您的 GUI 创建一个主事件循环。当任何功能达到需要更新 GUI 的程度时,请使用 write_event_value(key, value)
将事件写入主 window。示例:
def test():
import threading
layout = [[sg.Text('Testing progress bar:')],
[sg.ProgressBar(max_value=10, orientation='h', size=(20, 20), key='progress_1')]]
main_window = sg.Window('Test', layout, finalize=True)
current_value = 1
main_window['progress_1'].update(current_value)
threading.Thread(target=another_function,
args=(main_window, ),
daemon=True).start()
while True:
window, event, values = sg.read_all_windows()
if event == 'Exit':
break
if event.startswith('update_'):
print(f'event: {event}, value: {values[event]}')
key_to_update = event[len('update_'):]
window[key_to_update].update(values[event])
window.refresh()
continue
# process any other events ...
window.close()
def another_function(window):
import time
import random
for i in range(10):
time.sleep(2)
current_value = random.randrange(1, 10)
window.write_event_value('update_progress_1', current_value)
time.sleep(2)
window.write_event_value('Exit', '')
我刚开始学习 PySimpleGUI,我想创建一个自定义 GUI 进度条,它将在不同时间显示程序的哪些部分 运行。
例如,我有一个包含各种组件的视频处理程序,所以我希望进度条显示如下文本:
'Extracting Frame 1 from Video'
'Cropping images'
'Removing Duplicate Images'
但是所有这些行都需要从程序中的不同函数更新进度条 window,其中与包含进度条的 window 关联的 GUI 代码不是 运行。
我的代码:
image_name_list = Frame_Capture(f"{main_dir}\{input_line2}.mp4") # Generates image list of frames of video
Remove_Duplicates(image_name_list) # Removes duplicate images
print("Enter name of pdf file")
pdf_name = f'{input()}.pdf'
makePdf(pdf_name, image_name_list) # Converts images to pdf
Cleanup(image_name_list) # Deletes unneeded images
os.startfile(pdf_name)
在这里,当我的程序本身的 GUI 组件时,我需要从 'Frame_Capture'、'Remove_Duplicates'、'makePDF' 和 'Cleanup' 函数中更新 GUI Process 栏运行 在程序的另一部分。
我能想到的两种方案是:
- 全局创建我的 window 并全局更新其中的进度条
- 当我的程序到达需要更新进度条的部分时,将我所有的进度条语句逐行写入一个文本文件,同时每隔几毫秒将文本文件中的最新语句加载到我的进度条中。
这些解决方案听起来都不好。我还有其他方法可以做到这一点吗?
为您的 GUI 创建一个主事件循环。当任何功能达到需要更新 GUI 的程度时,请使用 write_event_value(key, value)
将事件写入主 window。示例:
def test():
import threading
layout = [[sg.Text('Testing progress bar:')],
[sg.ProgressBar(max_value=10, orientation='h', size=(20, 20), key='progress_1')]]
main_window = sg.Window('Test', layout, finalize=True)
current_value = 1
main_window['progress_1'].update(current_value)
threading.Thread(target=another_function,
args=(main_window, ),
daemon=True).start()
while True:
window, event, values = sg.read_all_windows()
if event == 'Exit':
break
if event.startswith('update_'):
print(f'event: {event}, value: {values[event]}')
key_to_update = event[len('update_'):]
window[key_to_update].update(values[event])
window.refresh()
continue
# process any other events ...
window.close()
def another_function(window):
import time
import random
for i in range(10):
time.sleep(2)
current_value = random.randrange(1, 10)
window.write_event_value('update_progress_1', current_value)
time.sleep(2)
window.write_event_value('Exit', '')