【问题标题】:Using PySimpleGUI to create a custom progress bar使用 PySimpleGUI 创建自定义进度条
【发布时间】:2021-04-08 11:37:46
【问题描述】:

我刚刚开始学习 PySimpleGUI,我想创建一个自定义 GUI 进度条,用于显示程序的哪些部分在不同时间运行。

例如,我有一个包含各种组件的视频处理程序,所以我希望进度条显示如下文本:

'从视频中提取第一帧'

'裁剪图像'

'删除重复图像'

但是所有这些行都需要从程序中的不同函数更新进度条窗口,其中与包含进度条的窗口相关联的 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 进程栏。

我能想到的两个解决方案是:

  1. 全局创建我的窗口并全局更新其中的进度条
  2. 当我的程序到达需要更新进度条的部分时,将我的所有进度条语句逐行写入文本文件,同时每隔几毫秒将文本文件中的最新语句加载到我的进度条中。李>

这些解决方案都不好听。有没有其他方法可以做到这一点?

【问题讨论】:

  • 首先尝试编写它,看看它是如何工作的。以及如何将progressbar 作为参数发送给函数 - Frame_Capture(..., my_progress_bar)
  • 你必须在函数里面做吗?你能在每个函数之前更新进度条吗?
  • @furas 听起来确实更容易。我会尝试这样做,但主要问题仍然存在。我有一个测试函数调用另一个函数,该函数调用另一个函数,该函数调用包含我发布的代码的函数。因此,我想我可以删除所有函数调用并将所有代码集成到一个函数中,该函数包含代码的 GUI 部分并从那里更新进度条,而不是调用我发布的 3 个深层函数的代码。但这会从程序中移除大量模块化,并使一个函数长达 200 行。

标签: python python-3.x user-interface tkinter pysimplegui


【解决方案1】:

为您的 GUI 创建一个主事件循环。当任何功能需要更新 GUI 时,使用write_event_value(key, value) 将事件写入主窗口。示例:

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

【讨论】:

    猜你喜欢
    • 2020-11-29
    • 2011-08-24
    • 2019-03-11
    • 2013-07-09
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 2015-10-30
    • 1970-01-01
    相关资源
    最近更新 更多