【问题标题】:How to get tkinter gui to update based off of results from code running in another thread?如何让 tkinter gui 根据在另一个线程中运行的代码的结果进行更新?
【发布时间】:2018-11-28 21:12:19
【问题描述】:

我目前正在使用 tkinter 和线程在 python 3 中开发一个小项目,以便制作一个与用户输入一起实时运行的程序。更具体地说,问题是我无法让 tkinter gui 从单独的线程更新。我尝试了一些涉及 .set 方法、.update_idletasks 和从回调启动线程的方法,但我根本无法让它工作。下面是一个简短的尝试,它启动一个线程,在按下 gui 中的按钮后应该继续增加计数器。

from tkinter import *
import threading

var = 0
class thread1 (threading.Thread):
   def __init__(self, threadID, name, counter):
      threading.Thread.__init__(self)
      self.threadID = threadID
      self.name = name
      self.counter = counter
   def run(self):
       while True:
           global var
           while True:
               var+=1
               window.update_idletasks()
examplethread = thread1(1, "example", 1)

window = Tk()
text = Label(window, text=var)
button = Button(window, text = "launch thread", command=examplethread.start)
text.pack()
button.pack()
window.mainloop

它不起作用,而是给我一个我知道的错误,说我不能在 mainloop() 正在运行的线程之外使用 tkinter 命令。我想知道是否可以更新 tkinter gui基于在同时输入其他玩家输入时在后台循环的代码的结果。

【问题讨论】:

    标签: python python-3.x multithreading tkinter


    【解决方案1】:
    1. tkinter Labels 使用 textvariable 参数而不是 text 来设置要使用的变量。

    2. 与您的标签一起使用的变量未声明为StringVar()

    3. 您必须使用.set() 为您的StringVar() 变量分配值,而不是正常的python 分配。

    4. 用一个变量做你的计数器,然后将var设置为那个变量

    5. 您的代码中包含 run 时,您似乎调用了错误的方法 start

    from tkinter import *
    import threading
    
    count=0
    
    class thread1 (threading.Thread):
        def __init__(self, threadID, name, counter):
            threading.Thread.__init__(self)
            self.threadID = threadID
            self.name = name
            self.counter = counter
    
        def run(self):
            while True:
                global count
                #while True:
                count+=1
                var.set(count)
                window.update_idletasks()
                
                
    examplethread = thread1(1, "example", 1)
    
    window = Tk()
    var=StringVar()
    var.set(0)
    text = Label(window, textvariable=var)
    button = Button(window, text = "launch thread", command=examplethread.start)
    text.pack()
    button.pack()
    window.mainloop()
    

    【讨论】:

    • 这是一个很好的解决方案,但仅供参考,examplethread.run 应该是 examplethread.start 您提供的代码仍然在同一个线程上运行。更多信息在这里stackoverflow.com/a/32383044/12148778
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-21
    • 1970-01-01
    • 2011-01-25
    • 1970-01-01
    • 1970-01-01
    • 2012-06-22
    相关资源
    最近更新 更多