Python 使用进度条显示函数的执行进度
我有一个计算两个整数之和的函数。我想用tkinter进度条显示这个sum函数的执行状态 这是我的方法,但它在执行sum函数后显示进度条,我想在sum函数执行时显示进度条,进度应该根据函数的执行时间来指示Python 使用进度条显示函数的执行进度,python,function,tkinter,progress-bar,execution-time,Python,Function,Tkinter,Progress Bar,Execution Time,我有一个计算两个整数之和的函数。我想用tkinter进度条显示这个sum函数的执行状态 这是我的方法,但它在执行sum函数后显示进度条,我想在sum函数执行时显示进度条,进度应该根据函数的执行时间来指示 我没有找到满足我要求的答案。如果有人能帮我,那就太好了。你的问题很有趣,但你的方法是完全错误的。 它首先执行sum,因为GUI尚未到达mainloop 所以,在GUI到达mainloop之后,它开始等待事件,因为GUI编程的事件驱动特性,比如按钮按下。换句话说:如果请求回调tkinter,则在m
我没有找到满足我要求的答案。如果有人能帮我,那就太好了。你的问题很有趣,但你的方法是完全错误的。 它首先执行sum,因为GUI尚未到达mainloop 所以,在GUI到达mainloop之后,它开始等待事件,因为GUI编程的事件驱动特性,比如按钮按下。换句话说:如果请求回调tkinter,则在mainloop之前不能调用函数 另一个问题是tkinter是单线程的,因此gui只能在函数运行结束时进行自我更新。所以,若您在函数中启动一个循环,那个么也并没有对gui的回调,但您可以从循环中调用函数,并在每次迭代中更新gui!e、 g.自生成事件的循环,由生成事件或之后的方法组成 看在上帝的份上,若函数并没有完全执行,progressbar怎么知道函数的执行时间呢?如果有人知道,请发表评论 但如果你敢,你可以开始玩多线程和队列 在我的示例中,进度条与函数的执行并行更新,这要归功于执行函数的独立线程,以及函数响应所在的队列,进度条是根据该队列更新的 使用python 3.5对其进行了测试:
import sys
import ttk
from Tkinter import *
from timeit import default_timer as timer
def sum(a, b):
for i in range(10):
c = a + b
print "Sum", c
time.sleep(5)
return c
mGui = Tk()
mGui.title('Progress')
mpb = ttk.Progressbar(mGui,orient ="horizontal", length = 200, mode ="determinate")
mpb.pack()
mpb.start()
mpb["maximum"] = 100
Start_Timer=timer()
sum(3,4)
Stop_Timer=timer()
Execution_Time=Stop_Timer-Start_Timer
mpb["value"] = Execution_Time
mGui.mainloop()
链接:
try:
import Tkinter as tk # Python 2
import ttk
import Queue as queue
except ImportError:
import tkinter as tk # Python 3
import tkinter.ttk as ttk
import queue
import threading
import time
class ThreadFunc(threading.Thread):
def __init__(self, loop_time=1.0 / 60):
super(ThreadFunc, self).__init__()
self.queue = queue.Queue()
self.timeout = loop_time
self.parent = None
self.stop_on_complete = None
self.running = False
self._stop = threading.Event()
def start_thread(self, parent, stop_on_complete=False):
# thread can wait for functions if not stop_on_complete
self.parent = parent
self.stop_on_complete = stop_on_complete
self.running = True
self.start()
def put_function(self, function, *args, **kwargs):
# put another function in queue
self.queue.put((function, args, kwargs))
def run(self):
print('### STARTED ###')
while self.running:
try:
function, args, kwargs = self.queue.get(timeout=self.timeout)
print('### RUNNING ###')
function(*args, **kwargs)
except queue.Empty:
if self.stop_on_complete:
self.stop()
else:
self.idle()
def stop(self):
print('### STOPPED ###')
self.running = False
self._stop.set()
@staticmethod
def idle():
print('### IDLE ###')
class App(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.resizable(width=False, height=False)
self.minsize(width=400, height=25)
self.wm_title('Another SO Example with progressbar')
self.queue = queue.Queue()
self.thread = None
self.in_work = False
self.mpb_frame = tk.Frame(self)
self.mpb = ttk.Progressbar(self.mpb_frame, orient='horizontal', length=400, mode='determinate')
self.mpb.pack()
self.mpb_frame.pack()
self.mpb.bind('<Map>', self.start_example)
def start_example(self, event=None):
if self.in_work:
return
self.in_work = True
self.spawn_thread(sum_func, 4, 3, self.queue)
def spawn_thread(self, command, *args):
# spawn a thread
self.thread = ThreadFunc()
self.thread.start_thread(self, True)
self.thread.put_function(command, *args)
self.periodic_call()
def periodic_call(self):
# check if our thread is running and if so - update progressbar
self.check_queue()
try:
self.thread.is_alive()
self.after(100, self.periodic_call)
except TypeError:
self.in_work = False
self.quit()
def check_queue(self):
# "transfer" messages to mpb-progressbar steps (10 iteration over you sum)
while self.queue.qsize():
try:
self.queue.get(0)
self.mpb.step(10)
except queue.Empty:
pass
def sum_func(a, b, queue_local):
# your sum function
for i in range(10):
c = a + b
time.sleep(1)
queue_local.put(c)
print('Sum', c)
app = App()
app.mainloop()