【问题标题】:Threading with Tkinter done right (with or without queues)正确使用 Tkinter 进行线程处理(有或没有队列)
【发布时间】:2014-03-13 14:59:42
【问题描述】:

我有一个更高级的代码,但这一切都来自这个简单的例子:

from Tkinter import *
import time

def destroyPrint():
    global printOut
    try:
        printOut.destroy()
    except:
        pass


def sendData():
    global new
    global printOut
    for i in range(6):
        destroyPrint()
        time.sleep(1)
        printOut=Label(new,text=i,font=('arial',15,'bold'))
        printOut.place(x=300,y=500)


def newWindow():
    global new
    print("ok")
    new=Toplevel()
    new.minsize(800,600)
    functionButton=Button(new,text="Send me",width=20,height=20, command=sendData)
    functionButton.place(x=300,y=150)


main = Tk()
main.minsize(800, 600)
menu=Button(main,text="Send data",width=20,height=20, command=newWindow)
menu.place(x=300,y=150)
mainloop()

在这个简单的示例中,我想启动 sendData 函数,该函数将在每次循环迭代时相应地更新 printOut Label。我们都知道它不会,它会挂起,直到函数完成,并打印最后一个数字 (5)。

我尝试了无数关于线程和队列的示例,但我失败了。 请简单说明一下这个例子,当函数中有 Tkinter 元素需要在另一个线程中执行时,如何正确执行线程。

我真的很沮丧,我在这一步上花了最后 2 天...

【问题讨论】:

  • 您的真实代码是否不仅仅在屏幕上显示数据?你可能需要也可能不需要线程,这取决于你真正想做的事情。
  • 它通过套接字连接到多个主机。问题是当服务器没有在主机上运行并且客户端尝试连接时......gui挂起......它肯定需要线程。
  • 基本上我希望它在屏幕上显示数据......并且 GUI 在尝试连接时不会挂起

标签: python multithreading callback tkinter queue


【解决方案1】:

你必须添加 update_idletasks() 来更新标签。而不是破坏和创建,只需更新 text ,并在 Tkinter 中使用 after() 而不是 sleep ,因为它会产生一个新进程,而 time.sleep() 在睡眠时挂起程序。

from Tkinter import *
import time

def sendData():
    global new
    ##global printOut
    printOut=Label(new,text="0",font=('arial',15,'bold'))
    printOut.place(x=300,y=500)
    for x in range(6):
        ##destroyPrint()
        printOut.config(text=str(x))
        new.update_idletasks()
        time.sleep(1)

def newWindow():
    global new
    print("ok")
    new=Toplevel()
    new.minsize(800,600)
    functionButton=Button(new,text="Send me",width=20,
                  height=20, command=sendData)
    functionButton.place(x=300,y=150)


main = Tk()
main.minsize(800, 600)
menu=Button(main,text="Send data",width=20,height=20, command=newWindow)
menu.place(x=300,y=150)
main.mainloop()

【讨论】:

  • 酷,现在如果我只能让“新”窗口始终响应?我认为你需要线程...
  • 学习课程的时间。实例属性/变量在整个类名称空间中都可用,并且可以在类中的任何位置访问。
  • 您的评论到底说明了什么?只能通过课程来完成吗?对于通过全局变量的普通函数来说,同样的事情不是这样吗?如果我将我的示例转移到课堂上,您会向我展示我所追求的解决方案吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-17
  • 2011-09-06
  • 1970-01-01
  • 1970-01-01
  • 2014-05-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多