简体   繁体   English

使用 PySimpleGUI 创建自定义进度条

[英]Using PySimpleGUI to create a custom progress bar

I have just started learning PySimpleGUI and I wanted to create a custom GUI progress bar that will display what parts of the program are running at different times.我刚刚开始学习 PySimpleGUI,我想创建一个自定义 GUI 进度条,显示程序的哪些部分在不同时间运行。

For example, I have a video processing program with various components so I want the progress bar to display text like:例如,我有一个包含各种组件的视频处理程序,所以我希望进度条显示如下文本:

'Extracting Frame 1 from Video' '从视频中提取第一帧'

'Cropping images' '裁剪图像'

'Removing Duplicate Images' '删除重复图像'

But all these lines require updating the progress bar window from different functions in the program where the GUI code associated with the window containing the progress bar is not running.但是所有这些行都需要从程序中的不同函数更新进度条 window,其中与包含进度条的 window 关联的 GUI 代码未运行。

My code:我的代码:

    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)

Here, I need to update the GUI Process bar from within the 'Frame_Capture', 'Remove_Duplicates', 'makePDF' and 'Cleanup' functions when the GUI component of my program itself is running in another part of the program.在这里,当我的程序本身的 GUI 组件在程序的另一部分运行时,我需要从“Frame_Capture”、“Remove_Duplicates”、“makePDF”和“Cleanup”函数中更新 GUI 进程栏。

The two solutions I can think of are:我能想到的两个解决方案是:

  1. Creating my window globally and updating the progress bar in it globally全局创建我的 window 并全局更新其中的进度条
  2. Writing all my progress bar statements into a text file line by line when my program reaches a part where the progress bar needs to be updated and simultaneously loading the latest statement from the text file into my progress bar every few milliseconds.当我的程序到达需要更新进度条的部分时,将我所有的进度条语句逐行写入文本文件,同时每隔几毫秒将文本文件中的最新语句加载到我的进度条中。

Neither of these solutions sound good.这些解决方案听起来都不好。 Is there some other way I can do this?还有其他方法可以做到这一点吗?

Make a main event loop for your GUI.为您的 GUI 创建一个主事件循环。 When any function comes to a point that GUI needs to be updated, write an event to your main window using write_event_value(key, value) .当任何 function 需要更新 GUI 时,使用write_event_value(key, value)将事件写入主 window 。 Example:例子:

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', '')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM