Tkinter进度条与Excel

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

我试图使用Tkinter来做到这一点,但遇到了问题。 我可以得到一个进度条popup,但阻止Excel运行,直到closures进度条的窗口。 我不能把它放在不同的线程中,因为我希望能够根据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() 

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

 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()) 

有了这个代码,当我调用macros时,会popup一个加载条,但会阻止Excel。 如果我closures窗口,它会继续。 如果我将mainloop调用移动到mainloop的末尾,那么整个terminal会加载,然后popup加载栏。 我无法让他们同时工作。

先谢谢您的帮助!

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

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

 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()