I've written some python 3.1 code (really simple as im no programmer) and I'm trying to put a GUI in it using tkinter 8.5 and python 3.1.4. The problem I'm having is开发者_JS百科 that the progress bar won't start. Here's the part of the code:
def transformation(Xn,Yn,Zn,const):
infile = filedialog.askopenfile('r')
outfile = filedialog.asksaveasfile('w')
pbar.start()
for line in infile.readlines():
inlist = line.split(" ")
inlist = [float(i) for i in inlist]
l = (Xn+Yn+Zn)/const**2
Xm = inlist[0] + Xn*l
Ym = inlist[1] + Yn*l
Zm = inlist[2] + Zn*l
outlist=[0,0,0]
outlist[0] = inlist[0] + 2*(Xm-inlist[0])
outlist[1] = inlist[1] + 2*(Ym-inlist[1])
outlist[2] = inlist[2] + 2*(Zm-inlist[2])
outdata = str('%.4f' %outlist[0])+" "+str('%.4f' %outlist[1])+" "+str('%.4f' %outlist[2])+"\n"
outfile.writelines(outdata)
infile.close()
outfile.close()
pbar.stop()
The function is being called by a button. I give all the files needed for the programm to work. The calculation is successfully completed but the bar never starts. Any ideas?
Thanks, AlexTh
The bar is starting, you're just not seeing it because you don't give the UI a chance to redraw. By the time the screen redraws you have stopped the progress bar. Redraws happen in response to redraw events, and those events get processed by the event loop. While your code is in the loop that reads the data you are preventing the event loop from running.
You will need to either a) use a thread or separate process to do your IO so as not to starve the event loop, b) you need to break your processing up into small chunks that can be done during each iteration of the event loop, or c) call update_idletasks
during each iteration of your loop; this method processes "idle" events which includes screen refreshes.
Google for "tkinter long running calculation" for lots of advice.
You need to update the progress bar with step or set, or change the value of the IntVar variable that is attached to the progress bar.
This might help. This example starts a main window, which can open multiple progress bars that are incremented in a loop via the automatic method. Your deadlines loop serves the purpose of the automatic method in this little example.
import tkinter as tk from tkinter import ttk import time
class main_window:
def __init__(self):
self.pbars = []
self.parent = tk.Tk()
self.parent.title('multiprocessing progess bar')
frame = ttk.Labelframe(self.parent)
frame.pack(pady=10, padx=10)
btn = tk.Button(frame, text="Cancel")
btn.bind("<Button-1>", self.cancel)
btn.grid(row=0, column=1, pady=10)
btn = tk.Button(frame, text="progress_bar")
btn.bind("<Button-1>", self.pbar)
btn.grid(row=0, column=2, pady=10)
btn = tk.Button(frame, text="increment")
btn.bind("<Button-1>", self.increment)
btn.grid(row=0, column=3, pady=10)
self.parent.mainloop()
def pbar(self, event):
count= len(self.pbars)
name="producer %d" % count
print (count*10)
self.pbars.append(pbar_dialog(self.parent, title=name, count=count*10))
pbar.automatic()
def cancel(self, event):
self.parent.destroy()
def increment(self, event):
for pbar in self.pbars:
pbar.step(10)
class pbar_dialog:
toplevel=None
pbar_count = 0
def __init__(self, parent, count=0, title=None):
self.pbar_value = count
self.title=title
pbar_dialog.pbar_count += 1
if not pbar_dialog.toplevel:
pbar_dialog.toplevel= tk.Toplevel(parent)
self.frame = ttk.Labelframe(pbar_dialog.toplevel, text=title)
#self.frame.pack()
self.pbar = ttk.Progressbar(self.frame, length=300, variable=self.pbar_value)
self.pbar.grid(row=0, column=1, columnspan=2, padx=5, pady=5)
btn = tk.Button(self.frame, text="Cancel")
btn.bind("<Button-1>", self.cancel)
btn.grid(row=0, column=3, pady=10)
self.frame.pack()
self.pbar.step(count)
def set(self,value):
self.pbar_value=value
def step(self,increment=1):
self.pbar.step(increment)
def cancel(self, event):
self.destroy()
def destroy(self):
self.frame.destroy()
pbar_dialog.pbar_count -= 1
if pbar_dialog.pbar_count == 0:
pbar_dialog.toplevel.destroy()
def automatic(self):
for i in range(self.pbar_value, 100):
time.sleep(1)
#self.step()
print(self.title, i)
self.set(i)
if name == 'main':
main_window()
精彩评论