2015-09-25 80 views
0

我需要一個進度條,它應該顯示程序在某個函數中的循環工作時仍在運行,因此所有問題都很簡單。Python Tkinter Progressbar在Toplevel上運行時不確定

我在這裏找到了一些有用的線程,但沒有人幫助我。我想我錯過了一個細節。

這裏是需要長達1分鐘的功能,這取決於有多少博客是用來完成:

def bildinhalt_execute(): 

     tumblr_progress.start() 
     taglist = tagliste_area.get("1.0", "end-1c") 
     taglist = taglist.split(",") 
     tumblr_alt_wert = tumblr_alt_wert_area.get("1.0", END) 
     """ Resized das Bild proportional """ 
     with open('tumblr_credentials.json', 'r') as daten: 
      data_for_login_tumblr_all = json.load(daten) 
     for blog in data_for_login_tumblr_all: 
      tumblr_zugangsdaten(data_for_login_tumblr_all[blog]["consumer_key"],data_for_login_tumblr_all[blog]["consumer_secret"],data_for_login_tumblr_all[blog]["oauth_token"],data_for_login_tumblr_all[blog]["oauth_token_secret"]) 
      im = Image.open(pfad_tumblr_1) 
      basewidth = (im.size[0] - int(breitepx_area.get("1.0", END))) 
      wpercent = (basewidth/float(im.size[0])) 
      height = int((float(im.size[1]) * float(wpercent))) 
      im = im.resize((basewidth, height), PIL.Image.ANTIALIAS) 
      im.save(pfad_tumblr_1) 
      """ Postet das Bild """ 
      pfad_tumblr_1_bild = pfad_tumblr_1 
      pfad_tumblr_1_bild = str(pfad_tumblr_1_bild) 
      tumblr_bild(blog, taglist, pfad_tumblr_1_bild, tumblr_alt_wert) 
     tumblr_progress.stop() 

我開始進步的開始和結束時停止。

tumblr_progress = ttk.Progressbar(tumblr_blog_root, orient='horizontal', mode='indeterminate') 
    tumblr_progress.place(x = 300, y = 615) 

當點擊該按鈕,這就是其中prograssbar應該開始出現進展

wordpress_button_bild = Button(tumblr_blog_root, text = "Bild", width=7, bg = "powder blue", command=bildinhalt_execute) 
    wordpress_button_bild.place(x = 10, y = 10) 

此刻正在執行的功能,我是在: 進度條本身的頂層根目錄中創建右邊?或者我有可能爲此使用多線程,從未與多線程工作可能非常困難,所以如果需要多線程,提示將很好從哪裏開始。

在此先感謝!

回答

0

假設您只想要一個移動的進度條,請使用「確定」模式並將間隔發送到start()函數。下面的標籤和計數器只是在那裏做一段時間。如果您希望進度條顯示類似完成百分比的內容,那麼您可以使用「之後」來安排函數調用以完成百分比更新進度條,這與標籤更新在下面的代碼中使用「之後」類似。

import Tkinter as tk 
from ttk import Progressbar 

class ProgressBar_Label(object): 
    def __init__(self, parent): 
     self.parent=parent 
     self.ctr=0 

     self.p = Progressbar(self.parent, orient=tk.HORIZONTAL, length=200, 
          mode='determinate') 
     self.p.grid() 
     self.p.start(75) ## 75 millisecond interval 

     self.label=tk.Label(self.parent, text="Start", bg="lightblue", width=10) 
     self.label.grid(row=1) 

     tk.Button(self.parent, text="Quit", bg="orange", 
        command=self.parent.quit).grid(row=10) 

     self.update_label() 

    def update_label(self): 
     self.ctr +=1 
     self.label["text"]=str(self.ctr) 
     if self.ctr < 100: 
      self.parent.after(100, self.update_label) 
     else: 
      self.p.destroy() 
      self.label["text"]="Finished" 

parent=tk.Tk() 
PL=ProgressBar_Label(parent) 
parent.mainloop() 
+0

可悲的是我已經試過,那不是我想要的。據我研究,我必須使用多線程,它不可能沒有。但是,謝謝你的幫助 – Roman

0

我不使用多處理,但下面的簡單示例工作。請注意,根窗口在流程之外啓動並傳遞給類,這在理論上保持獨立。

from multiprocessing import Process 
import time 

try: 
    import Tkinter as tk ## Python 2.x 
except: 
    import tkinter as tk ## Python 3.x 

class ProgressBar(): 
    def __init__(self, root): 
     self.root=root 
     self.root.geometry("75x50+900+100") 
     self.ctr=25 

    def mainloop(self): 
     self.root.mainloop() 

    def start_countdown(self): 
     """ a separate process in a separate GUI 
     """ 
     self.root.withdraw() 
     self.top_count=tk.Toplevel(self.root) 
     self.top_count.geometry("75x50+750+50") 
     self.label_ctr = tk.IntVar() 
     self.label_ctr.set(self.ctr) 
     label = tk.Label(self.top_count, textvariable=self.label_ctr) 
     label.pack() 
     if self.ctr > 0: 
      self.top_count.after(750, self.update) 

    def start_running(self): 
     """ create the progress bar widget 
     """ 
     self.top=tk.Toplevel(self.root, takefocus=True) 
     self.top.title("Progress Bar") 
     self.top.geometry("+700+200") 
     canvas = tk.Canvas(self.top, width=261, height=60, bg='lightgray') 
     canvas.pack() 

     rc2 = canvas.create_rectangle(15, 20, 243, 50, outline='blue', \ 
             fill='lightblue') 
     rc1 = canvas.create_rectangle(24, 20, 34, 50, outline='white', \ 
             fill='blue') 

     total=100 
     x = 5 
     while self.ctr:  ## move the small rectangle +5 or -5 units 
      total += x 
      if total > 311: 
       x = -5 
      elif total < 100: 
       x = 5 

      ## in a separate process so should not interfere with mainloop() 
      time.sleep(0.2) 
      canvas.move(rc1, x, 0) 
      canvas.update() 

    def update(self): 
     self.ctr -= 1 
     self.label_ctr.set(self.ctr) 

     if self.ctr > 0: 
      self.top_count.after(750, self.update) 
     else: 
      ## sleep to allow any remaining after() to execute 
      ## can also use self.root.after_cancel(id) 
      self.top_count.after(500, self.root.destroy) ## destroy root when zero is reached 

root = tk.Tk() 

PB=ProgressBar(root) 
pr1=Process(target=PB.start_countdown(), args=()) 
pr1.start() 

pr2=Process(target=PB.start_running(), args=()) 
pr2.start() 

## start mainloop in a separate process as a function of the class 
## don't know if this is really necessary or not 
## the theory is, it is detached from the other 2 processes and so 
## can react to both independently 
## also the mainloop() process can be killed=shut down properly 

pr3=Process(target=PB.mainloop(), args=()) 
pr3.start() 

## safety clean up 
pr1.terminate() 
pr2.terminate() 
pr3.terminate()