【问题标题】:Tkinter Progress Bar not workingTkinter 进度条不工作
【发布时间】:2014-07-30 12:08:44
【问题描述】:

我正在制作一个 Tkinter 应用程序,它将文件从用户系统复制到 FTP 服务器。 我想包含一个确定的进度条,它将显示通过服务器复制的文件的百分比进度。但是进度条不起作用,因为复制时窗口挂起。我已经为进度条使用了线程和不确定模式,但证明它没有用。请检查以下代码并建议适当的添加/修改。

from Tkinter import *
from ftplib import FTP
import ttk,threading,os,time,tkMessageBox

main_window=Tk()

def onCopy_buttonClick():                                   

    def ok_button_click():
        i=0
        global list1        
        for item in files:
            if(list1[i].get()==1):              
                Ftp=FTP_Entry.get()
                Ftp=Ftp.split("/",1)
                site=FTP(Ftp[0])
                site.login(User_Entry.get(),Password_Entry.get())
                site.cwd(Ftp[1])
                copy_window.withdraw()
                progress_window=Toplevel(copy_window)
                p_label=Label(progress_window,text="Please wait while the files are being copied..").pack()

                progressbar=ttk.Progressbar(progress_window,length=300,orient='horizontal',mode='determinate')
                progress=StringVar()
                progresslabel=Label(textvariable=progress).pack()
                progress.set("0 KBps")
                progressbar.pack()

                result=True

                for file in site.nlst():
                    if item==file:
                        result=tkMessageBox.askyesno("Warning !",item+" is already present. If you select Yes, item will be replaced.")

                if result==True:                    
                    def foo():
                        with open(item,"rb") as f:
                            site.storbinary("STOR "+item,f,blocksize=33554432)                              
                    def start_foo_thread():
                        foo_thread = threading.Thread(target=foo)
                        foo_thread.start()                          
                        size=int(os.path.getsize(item)) #item can be in GB's
                        copied=0        
                        '''while(copied!=size):
                            copied=int(site.size(item)) #doesn't get size till copying is done
                            progressbar['value']=round(copied/size)
                            progress.set(" KBps") #how?
                            time.sleep(1000)'''
                        while(True):
                            if foo_thread.is_alive()==False:
                                progressbar.stop()
                                break

                start_foo_thread()
            i=i+1   
        progress_window.destroy()
        copy_window.destroy()
        main_window.deiconify()

    os.chdir(Path_Entry.get())  
    copy_window=Toplevel(main_window)   
    main_window.withdraw()
    files=os.listdir(os.getcwd())
    global list1
    list1=[]
    for i in range(0,len(files)):
        list1.append("0")
        list1[i]=IntVar()
    i=0 
    for item in files:
        if os.path.isfile(item):
            c = Checkbutton(copy_window,variable=list1[i],text=item)
            c.pack()
        i=i+1
    ok_button=Button(copy_window,text="OK",command=ok_button_click).pack()


Path_Label=Label(text="Enter File path : ").grid(row=0,column=0)
Path_Entry=Entry()
Path_Entry.grid(row=0,column=1)
FTP_Label=Label(text="FTP Path : ").grid(row=1,column=0)
FTP_Entry=Entry()
FTP_Entry.grid(row=1,column=1)
User_Label=Label(text="Username : ").grid(row=2,column=0)
User_Entry=Entry()
User_Entry.grid(row=2,column=1)
Password_Label=Label(text="Password : ").grid(row=3,column=0)
Password_Entry=Entry()
Password_Entry.grid(row=3,column=1)
Copy_button=Button(text="START COPYING",command=onCopy_buttonClick)
Copy_button.grid(row=4,columnspan=2)
main_window.mainloop()

我现在已经编辑了代码,这就是它的外观,它符合我的目的。欢迎提出任何建议。

def ok_button_click():
        i=0
        global list1        
        for item in files:
            if(list1[i].get()==1):              
                Ftp=FTP_Entry.get()
                Ftp=Ftp.split("/",1)
                site=FTP(Ftp[0])
                site.login(User_Entry.get(),Password_Entry.get())
                site.cwd(Ftp[1])
                copy_window.withdraw()
                progress_window=Toplevel(copy_window)
                p_label=Label(progress_window,text="Please wait while the files are being copied..").pack()

                progressbar=ttk.Progressbar(progress_window,length=300,orient='horizontal',mode='determinate')              
                progressbar.pack()
                progress=StringVar()
                progresslabel=Label(progress_window,textvariable=progress)
                progresslabel.pack()
                progress.set("0 % Copied")

                result=True

                for file in site.nlst():
                    if item==file:
                        result=tkMessageBox.askyesno("Warning !",item+" is already present. If you select Yes, item will be replaced.")

                if result==True:    

                    def callback(block):
                        global sizewritten
                        sizewritten += 8388608                      
                    def foo():
                        with open(item,"rb") as f:
                            site.storbinary("STOR "+item,f,8388608,callback)    
                    def start_foo_thread():
                        filesize=int(os.path.getsize(item))
                        progressbar["maximum"] = filesize
                        foo_thread = threading.Thread(target=foo)
                        foo_thread.start()                      
                        while(True):
                            progressbar["value"]=sizewritten
                            percent=str(int(sizewritten/float(filesize)*100))
                            if (int(percent)>100):
                                percent="100"
                            progress.set(percent+" % Copied")   
                            progress_window.update()
                            if foo_thread.is_alive()==False:
                                progressbar.stop()
                                break

                start_foo_thread()
            i=i+1   
        progress_window.destroy()
        copy_window.destroy()
        main_window.deiconify()

【问题讨论】:

  • 我不完全理解你的代码,但我有一些一般性的建议。 Tkinter 程序中的while 循环往往会锁定界面,因为只要循环继续,系统就无法处理任何窗口事件。最好创建一个在不循环的情况下一次更新进度条的函数,然后使用 Tkinter 的 after 使该函数每 X 毫秒执行一次。这将为 Tkinter 提供处理窗口事件所需的空闲时间。
  • @Pranjal 您在一个 Tkinter 窗口中组合 .pack().grid() 犯了一个非常简单的错误,这可能是进度条无法按您希望的方式工作的原因 - 这里为什么:stackoverflow.com/questions/17267140/…
  • @W1ll1amvl:.grid() 用于 main_window,.pack() 用于 progress_window。我只有progress_window有问题,因为它在复制文件时挂起,我试图通过使用线程来解决这个问题,但徒劳无功。
  • 好的,我现在可以看到,copy_window 是做什么用的?您可以尝试仅使用网格也许会有所帮助?
  • 一旦我们点击 main_window 上的 Copy_button,copy_window 就会出现在所选文件夹中的文件名上。我们检查要复制的文件,然后按 ok_button 打开 progress_window 开始复制文件。

标签: python ftp tkinter progress-bar


【解决方案1】:

没有阅读所有代码的快速建议,但我略读并没有看到它。每次进度条应该增加时,请尝试更新您的根窗口。

【讨论】:

  • 非常有帮助,谢谢。我之前也尝试过,但当时没有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-23
  • 2013-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-03
  • 2017-08-28
相关资源
最近更新 更多