【问题标题】:Tkinter window freezes even if threading is used即使使用线程,Tkinter 窗口也会冻结
【发布时间】:2014-12-03 22:03:43
【问题描述】:

我正在制作一个下载文件的 Python 程序。我使用 Tkinter 作为 GUI,但它在下载较大的文件时会冻结,这会阻止缓冲区显示。我尝试使用线程,正如 S.O. 的类似问题中所建议的那样。但没有任何改变。代码如下:

labelText1 = StringVar()
labelText1.set("Double-click file to download...")
label11 = Label(app, textvariable=labelText1, height=2, bg="#DF1A2B", fg="white")
label11.place(x=50, y=50)

def download_file(url):
    file_name = url.split('/')[-1]
    u = urllib2.urlopen(url)
    f = open("./downloads/" + file_name, 'wb')
    meta = u.info()
    file_size = int(meta.getheaders("Content-Length")[0])
    print "Downloading: %s" % (file_name)
    os.system('cls')
    file_size_dl = 0
    block_sz = 8192
    while True:
        buffer = u.read(block_sz)
        if not buffer:
           break

        file_size_dl += len(buffer)
        f.write(buffer)
        status = r"%10d  [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size)
        status = status + chr(8)*(len(status)+1)
        labelText1.set(status,)
        tuple = (file_name, status)
    f.close()
    onEnd()

def onEnd():
    labelText1.set("Status: done!")

def double_clicked(clicked):
    tuple = mlb.get(clicked)[0]
    url = str(tuple[2])
    if tuple[1] != "Folder":
       t = threading.Thread(target=download_file(url))
       t.start()
    else:
        print "FOLDER HANDLING GOES HERE"

有没有其他方法可以让我在下载过程仍在运行时更改标签文本?

【问题讨论】:

  • 如果在 while 循环期间刷新 GUI 会发生什么,例如使用update()?
  • 您可能需要在while True: 循环中调用time.sleep(),如this question's code 所示。
  • @figs 这实际上解决了问题!现在 GUI 正在正常更新...你能把它作为答案让我接受吗?
  • 当然可以,很高兴它有帮助:)
  • 您在 Tkinter 中使用线程有点危险。通常你应该使用queue.queue之类的东西来与GUI线程通信,而不是简单地在小部件上调用set()。

标签: python multithreading tkinter


【解决方案1】:

仅仅因为它在一个单独的线程中,如果它有很长的代码部分(例如你的 while 循环),GUI 仍然可以“挂起”。在 while 循环期间添加 GUI 刷新,以便有机会重绘,例如使用update()

【讨论】:

    猜你喜欢
    • 2015-09-22
    • 2016-04-29
    • 1970-01-01
    • 2012-10-25
    • 2023-04-06
    • 2015-10-23
    • 1970-01-01
    • 1970-01-01
    • 2011-10-16
    相关资源
    最近更新 更多