代码之家  ›  专栏  ›  技术社区  ›  Annonymous

如何让tk在函数完成之前显示某些内容

  •  0
  • Annonymous  · 技术社区  · 12 年前

    我有一个代码,它下载在线列表中指定的文件,同时显示一个加载屏幕,其中带有一个标签,告诉用户正在下载哪个文件,并显示一个不确定的进度条,向用户显示正在发生的事情。下载工作得很好,但不起作用的是tkinter,它在过程完成后才起作用,只在最后显示“下载完成”标签。如何在函数完成之前让tkinter显示窗口?

    我已经试过了

    • 将其拆分为多个函数

    • 添加 sleep 函数,以查看减慢速度是否有帮助

    为了显示这一点,我用一些示例替换了我的原始代码。有人知道如何使tkinter更新更积极(在功能完成之前)吗?

    #Imports
    import urllib.request as ur
    import os
    from tkinter import *
    import tkinter.ttk as ttk
    import time as T
    
    #Globals
    tk = None
    where = None
    progressbar = None
    progresstitle = None
    progressinfo = None
    transfer = None
    
    #Make sure that the download directory exists
    def checkdir(filename):
        directory = os.path.dirname(filename)
        try:
            os.stat(directory)
        except:
            os.mkdir(directory)  
    
    #First part (read q to see why I split up)
    def part1():
        #Get Globals
        global tk
        global where
        global progressbar
        global progresstitle
        global progressinfo
        global transfer
    
        #Create Window
        tk = Tk()
        tk.title("Downloading...")
    
        #Find out the location of the online files to download by reading the online txt file which contains their locations
        where = str(ur.urlopen("http://example.com/whatfilestodownload.txt").read())
        where = where[2:(len(where)-1)]
        where = where.split(";")
        #Create the progress bar
        progressbar = ttk.Progressbar(tk, orient=HORIZONTAL, length=200, mode='indeterminate')
        progressbar.grid(row = 2, column = 0)
        #Create the labels
        progresstitle = Label(tk, text = "Downloading Files!", font = ("Helvetica", 14))
        progresstitle.grid(row = 0, column = 0)
        progressinfo = Label(tk, text = "Starting Download...", font = ("Helvetica", 10))
        progressinfo.grid(row = 1, column = 0)
    
        #Engage Part Two
        part2()
    
    #Part Two
    def part2():
        #Get Globals
        global tk
        global where
        global progressbar
        global progresstitle
        global progressinfo
        global transfer
        #Repeat as many times as files described in the only file describing .txt
        for x in where
            #The online file contains "onlinelocation:offlinelocation" This splits them up
            x1 = x.split(":")[0]
            x2 = x.split(":")[1]
    
            #Read the online file and update labels
            transfer = None
            progressinfo.config(text = str("Downloading " + x2 + "..."))
            transfer = str(ur.urlopen("http://example.com/" + x1).read())
            progressinfo.config(text = str("Configuring downloaded file..."))
            transfer = transfer [2:(len(transfer)-1)]
    
            #Fix python turning "\n" to "\\n" by reversing
            transfer = transfer.split("\\n")
            transtemp = ""
            for x in transfer:
                transtemp = transtemp + "\n" + x
            transfer = transtemp[1:len(transtemp)]
            progressinfo.config(text = str("Installing " + x2 + "..."))
            tw = None
            checkdir(str(os.getcwd()+"/Downladed/"+x2))
            tw = open(str(os.getcwd()+"/Downloaded/"+x2), "w")
            tw.write(transfer)
            tw.close()
            #See if waiting helps
            T.sleep(0.5)
        part3()
    def part3():
        #Get Globals
        global tk
        global where
        global progressbar
        global progresstitle
        global progressinfo
        global transfer
        #Final Screen
        progressbar.grid_remove()
        progressinfo.grid_remove()
        progresstitle.config(text="You have downloaded\n the required files!")
        progressbar.stop()
    
    part1()
    
    2 回复  |  直到 12 年前
        1
  •  1
  •   atlasologist    12 年前

    如果在您的 part2() 函数就足够了,您可以使用 update_idletasks() 方法,将其置于 T.sleep() ,这将允许GUI在返回到for循环的另一个迭代之间进行刷新。

    裁判: http://effbot.org/tkinterbook/widget.htm#Tkinter.Widget.update_idletasks-method

        2
  •  1
  •   patthoyts    12 年前

    这就是Tcl具有异步I/O功能的原因。您需要及时处理窗口系统事件,这样就不能等待下载完整的文件。相反,你需要把它分成几块。在Tcl中,我们将使用fileevent命令设置一个过程,每当套接字中有输入可用时调用该过程。剩下的时间我们可以处理其他事件。在Python中,常见的方法是Twisted包。这允许您使用twisted注册事件源,并使整个应用程序面向事件。您也可以使用线程并在工作线程上进行下载,但这并不能真正帮助您处理进度通知。有一些特殊的处理来连接Tkinter和Twisted-请参阅 documentation .