2011-09-05 45 views
0

我已經寫了一些python 3.1代碼(真的很簡單,因爲我沒有程序員),我試圖把tkinter 8.5和python 3.1 0.4。我遇到的問題是進度條無法啓動。以下是部分代碼:ttk.Progressbar使用python 3.1.4 tkinter 8.5不會啓動

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

該功能正在通過按鈕調用。我提供了程序工作所需的所有文件。計算成功完成,但酒吧從不開始。有任何想法嗎?

感謝, AlexTh

回答

0

酒吧開始,你只是沒有看到它,因爲你不給用戶界面有機會重繪。當屏幕重繪時,您已停止進度條。重繪發生在響應重畫事件,並且這些事件由事件循環處理。當您的代碼處於讀取數據的循環中時,您將阻止事件循環運行。

您將需要a)使用一個線程或單獨的進程來完成您的IO,以免捱餓事件循環,b)您需要將處理分解成可在每次迭代過程中完成的小塊事件循環,或c)在循環的每次迭代期間調用update_idletasks;此方法處理包含屏幕刷新的「空閒」事件。

Google對於「tkinter長時間運行計算」有很多建議。

+0

可以同時plz幫助我如何在上面的代碼中使用update_idletasks命令?不幸的是,我不是一位編程專家。我只是想爲我所擁有的一個項目製作一個體面的應用程序。謝謝! – AlexTh

+0

@AlexTh:作爲開始,嘗試在循環結束時調用'root.update_idletasks()'(用你稱之爲'Tk'實例的引用來代替'root')。不要在循環後執行它,因爲它在每次迭代中都會被調用。 –

+0

root.update_idletasks不起作用。相反,root.update()在outfile.writelines(outdata)行之後的循環內正常工作。 – AlexTh

0

您需要使用步驟或設置更新進度欄,或者更改附加到進度欄的IntVar變量的值。

這可能有幫助。本示例啓動一個主窗口,該窗口可以打開多個進度條 ,這些進度條通過自動方法在循環中遞增。在這個小例子中,您的截止日期循環服務於自動方法的目的。

進口Tkinter的傳統知識 從Tkinter的進口TTK 進口時間

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

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

如果 =='主要 ':

main_window()