使用Excel的Tkinter进度条

时间:2017-09-28 22:16:15

标签: python excel tkinter

我们有一个Pyxll应用程序(用python编写的Excel应用程序),它会在打开工作簿时发出大量请求来获取数据。我们希望在发出请求时向用户显示加载栏,并在每次请求返回后更新加载栏。

我正在尝试使用Tkinter执行此操作,但遇到了问题。我可以弹出一个进度条,但它会阻止Excel运行,直到您关闭进度条的窗口。我不能把它放在不同的线程中,因为我希望能够根据HTTP请求何时返回来更新进度。有一个简单的方法吗?

到目前为止,这是我的代码。我做了一个基本的装载栏类:

import Tkinter as tk
import ttk

class OrderingProgressBar(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        # progress goes from 0-100 (for percentage)
        self.progress = 0
        self.max_progress = 100

        self.progress_bar = ttk.Progressbar(self, orient="horizontal", length=200, mode="determinate", maximum=self.max_progress)
        self.progress_bar.pack()

然后我有一个宏被调用来启动应用程序并开始发出请求。

def launch_ordering_terminal(ribbon):
    """Launch all of the apps required for the Ordering Terminal"""
    ordering_progress_bar = OrderingProgressBar()
    ordering_progress_bar.mainloop()

    excel_utils.turn_off_excel_updates(xl_app())
    launch_allocation_app(manager_id)
    ordering_progress_bar.progress_bar.step(25)
    launch_si_app(manager_id)
    ordering_progress_bar.progress_bar.step(25)
    launch_accounting_app(manager_id)
    ordering_progress_bar.progress_bar.step(25)
    launch_reports_builder(terminal_mode)
    ordering_progress_bar.progress_bar.step(25)
    excel_utils.turn_on_excel_updates(xl_app())

使用此代码,当我调用宏时,会弹出一个加载栏,但阻止Excel。如果我关闭窗口,它会继续。如果我将mainloop调用移至launch_ordering_terminal的末尾,则会加载整个终端,然后弹出加载栏。我不能让他们同时工作。

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

维护GUI是一项全职工作,需要无限循环,称为“mainloop”。如果你想在此期间做其他事情,你需要将它添加到mainloop,或者在另一个线程中执行。在你的情况下,我认为一个新的线程将是最简单的。 Tkinter在主线程中运行最佳,因此将代码放在子线程中。

作为一个完全未经测试的猜测:

from threading import Thread

def do_stuff(ordering_progress_bar):
    excel_utils.turn_off_excel_updates(xl_app())
    launch_allocation_app(manager_id)
    ordering_progress_bar.progress_bar.step(25)
    launch_si_app(manager_id)
    ordering_progress_bar.progress_bar.step(25)
    launch_accounting_app(manager_id)
    ordering_progress_bar.progress_bar.step(25)
    launch_reports_builder(terminal_mode)
    ordering_progress_bar.progress_bar.step(25)
    excel_utils.turn_on_excel_updates(xl_app())
    ordering_progress_bar.quit() # kill the GUI

def launch_ordering_terminal(ribbon):
    """Launch all of the apps required for the Ordering Terminal"""
    ordering_progress_bar = OrderingProgressBar()
    t = Thread(target=do_stuff, args=(ordering_progress_bar,))
    t.start()
    ordering_progress_bar.mainloop()