Python Tkinter Progressbar在函数运行时在Toplevel上不确定

时间:2015-09-25 12:48:07

标签: python tkinter progress-bar

我需要一个进度条,它应该表明当某个函数中的循环工作时程序仍在运行,所以问题都很简单。

我在这里发现了一些有用的线索,但没有人帮助我。我想我错过了一个细节。

根据使用的博客数量,这个功能最多需要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)

我在右边吗?或者我可能为此使用多线程,从来没有使用多线程可能非常难,所以如果需要多线程,提示将是很好的从哪里开始。

提前致谢!

2 个答案:

答案 0 :(得分: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()

答案 1 :(得分: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()