Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何让tk在函数完成之前显示某些内容_Python_Python 3.x_Tkinter_Ttk - Fatal编程技术网

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

Python 如何让tk在函数完成之前显示某些内容,python,python-3.x,tkinter,ttk,Python,Python 3.x,Tkinter,Ttk,我有这段代码,可以下载在线列表中指定的文件,同时显示一个加载屏幕,屏幕上有一个标签,告诉用户正在下载哪个文件,还有一个不确定的进度条,向用户显示正在发生的事情。下载效果很好,但tkinter不起作用,它在下载过程完成之前不起作用,只在最后显示“下载完成”标签。如何让tkinter在函数完成之前显示窗口 #Imports import urllib.request as ur import os from tkinter import * import tkinter.ttk as ttk imp

我有这段代码,可以下载在线列表中指定的文件,同时显示一个加载屏幕,屏幕上有一个标签,告诉用户正在下载哪个文件,还有一个不确定的进度条,向用户显示正在发生的事情。下载效果很好,但tkinter不起作用,它在下载过程完成之前不起作用,只在最后显示“下载完成”标签。如何让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()
我已经试过了

  • 将其拆分为多个功能

  • 添加
    sleep
    功能以查看减慢睡眠速度是否有帮助

为了显示我所说的内容,我用一些示例替换了我的原始代码。是否有人知道如何使tkinter更新更积极(在函数完成之前)


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

如果在
part2()
函数中更新下载的每个文件末尾的显示就足够了,您可以使用
update\u idletasks()
方法,将其替换为
T.sleep()
,这将允许GUI在返回到for循环的另一个迭代之间刷新

参考: