赞
踩
下面是一些演示如何做你想做的事情。它之所以有效,是因为在主线程以外的线程中运行的代码不会进行任何tkinter调用。为了让线程一个接一个地按顺序运行,它使用一个FIFOQueue表示每个线程的条目,并在最后一个线程完成后开始新的线程的运行。在
要按照start_all()函数中所做的那样,按照一定的顺序“调度”一系列步骤,只需put()按照它们应该在此job_queue的顺序执行每个步骤。在
这一切都是通过反复使用通用的^{}方法定期运行一个“polling”函数(名为poll)来完成的,该函数检查另一个线程当前是否正在执行,并相应地作出反应。在
在代码中,每个线程所做的处理被称为“步骤”或“作业”。在from queue import Queue, Empty
import random
import tkinter as tk
from tkinter import ttk
import tkinter.messagebox as tkMessageBox
from threading import Thread
from time import sleep
random.seed(42) # Generate repeatable sequence for testing.
ITERATIONS = 100
POLLING_RATE = 100 # millisecs.
# Global variables
cur_thread = None # Current running thread.
cur_button = None
cur_name = None
job_queue = Queue() # FIFO queue.
def sample_function():
for i in range(1, ITERATIONS):
print(i)
sleep(0.01) # Simulate slow I/O.
def start_thread(name, func, btn_variable):
global cur_thread, cur_button
if cur_thread is not None:
tkMessageBox.showerror('Error', "You can't start a step when there"
" are some already running.")
return
cur_thread = Thread(target=func)
cur_button = btn_variable
btn_variable.configure(style='blue.TButton')
cur_thread.start()
def poll(window, processing_bar):
global cur_thread, cur_button
if cur_thread is not None:
if cur_thread.is_alive():
processing_bar.step()
else:
cur_thread.join() # Should be immediate.
cur_thread = None
processing_bar.stop()
cur_button.configure(style='green.TButton')
window.update()
elif not job_queue.empty(): # More to do?
try:
job_info = job_queue.get_nowait() # Non-blocking.
start_thread(*job_info)
processing_bar.start()
window.update()
except Empty: # Just in case (shouldn't happen).
pass
window.after(POLLING_RATE, poll, window, processing_bar)
# Button commands.
def prepare_clicked():
start_thread('prepare', sample_function, prepare_btn)
def social_clicked():
start_thread('social', sample_function, social_btn)
def anomaly_clicked():
start_thread('anomaly', sample_function, anomaly_btn)
def scoring_clicked():
start_thread('scoring', sample_function, scoring_btn)
def dashboard_clicked():
start_thread('dashboard', sample_function, dashboard_btn)
def start_all():
global job_queue
# Put info for each step in the job queue to be run.
for job_info in (('prepare', sample_function, prepare_btn),
('social', sample_function, social_btn),
('anomaly', sample_function, anomaly_btn),
('scoring', sample_function, scoring_btn),
('dashboard', sample_function, dashboard_btn)):
job_queue.put(job_info)
# Start the polling.
window.after(POLLING_RATE, poll, window, processing_bar)
####
window = tk.Tk()
#window = tk.Toplevel()
topFrame = tk.Frame(window)
bottomFrame = tk.Frame(window)
# Tell the Frame to fill the whole window
topFrame.pack(fill=tk.BOTH, expand=1)
bottomFrame.pack(fill=tk.BOTH, expand=1)
# Make the Frame grid contents expand & contract with the window
topFrame.columnconfigure(0, weight=1)
for i in range(5):
topFrame.rowconfigure(i, weight=1)
bottomFrame.rowconfigure(0, weight=1)
for i in range(3):
bottomFrame.columnconfigure(i, weight=1)
ttk.Style().configure('blue.TButton', foreground='blue')
ttk.Style().configure('green.TButton', foreground='green')
ttk.Style().configure('red.TButton', foreground='red')
prepare_btn = ttk.Button(topFrame, command=prepare_clicked, text='Button 1', style='red.TButton')
anomaly_btn = ttk.Button(topFrame, command=anomaly_clicked, text='Button 2', style='red.TButton')
social_btn = ttk.Button(topFrame, command=social_clicked, text='Button 3', style='red.TButton')
scoring_btn = ttk.Button(topFrame, command=scoring_clicked, text='Button 4', style='red.TButton')
dashboard_btn = ttk.Button(topFrame, command=dashboard_clicked, text='Button 5', style='red.TButton')
commentary = ttk.Button(bottomFrame, text='START', width=10, command=start_all)
commentarylabel = ttk.Label(bottomFrame, text=' Commentary ', width=25)
processing_bar = ttk.Progressbar(bottomFrame, orient='horizontal', mode='indeterminate')
prepare_btn.grid (row=0, column=0, columnspan=1, sticky='EWNS')
anomaly_btn.grid (row=1, column=0, columnspan=1, sticky='EWNS')
social_btn.grid (row=2, column=0, columnspan=1, sticky='EWNS')
scoring_btn.grid (row=3, column=0, columnspan=1, sticky='EWNS')
dashboard_btn.grid (row=4, column=0, columnspan=1, sticky='EWNS')
commentary.grid (row=0, column=0, columnspan=1, sticky='EWNS')
commentarylabel.grid(row=0, column=1, columnspan=2, sticky='EWNS')
processing_bar.grid (row=0, column=3,columnspan=1, sticky='EWNS')
window.after(POLLING_RATE, poll, window, processing_bar)
window.mainloop()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。