【问题标题】:Python tkinter threading and window refreshPython tkinter 线程和窗口刷新
【发布时间】:2020-05-29 18:06:46
【问题描述】:

我正在使用 python 和 tkinter 构建一个可以刷新和可视化更新对象的可视化工具。现在,对象无法更改,因为线程不工作。任何帮助或一般知识将不胜感激。我对线程和 tkinter 比较陌生。

我要摄取的示例对象

class color1:
    def __init__(self, color):
       self.color = color

    def change_col(self, new_color):
        self.color = new_color

    def pass_col(self):
        return(self)

我的可视化代码

class my_visual(threading.Thread):

    def __init__(self, col1):
        threading.Thread.__init__(self)
        self.start()
        self.col1 = col1

    def viz(self):
        self.root = Tk()
        btn1 = Button(self.root, text = 'Refresh', command = self.refresh)
        btn1.pack()
        frame = Frame(self.root, width = 100, height = 100, bg = self.col1.color)
        frame.pack()
        btn2 = Button(self.root, text = 'Close', command = self.exit)
        btn2.pack()
        self.root.mainloop()

    def refresh(self):
        self.root.quit()
        self.root.destroy()
        self.col1 = self.col1.pass_col()
        self.viz()


    def exit(self):
        self.root.quit()
        self.root.destroy()

有效的代码

c = color1('RED')
test = my_visual(c)
test.viz()

无效的代码

在这个版本中,刷新工作,但线程没有。当线程工作时,刷新不会发现对象已更改。

c.change_col('BLUE')

【问题讨论】:

  • 为什么需要线程?这似乎增加了一堆开销而没有提供任何好处。
  • 虽然你的类继承自threading.Thread类,但是派生类没有包含run()函数。这意味着start() 不会做任何事情。对于您的情况,不需要使用线程。

标签: python multithreading tkinter


【解决方案1】:

如果您扩展 threading.Thread 类,您需要使用您的自定义功能覆盖 run() 方法。如果没有 run 方法,线程会立即死亡。您可以使用my_visual.is_alive() 测试线程是否处于活动状态。

【讨论】:

  • 我绝对需要对此进行更多调查。我想我要把线程移到课堂之外,因为项目已经发生了一些变化。感谢您的回复
【解决方案2】:

问题是你的test.viz() 是一个无限循环,因为self.root.mainloop(),所以一旦你调用了那个函数,你就不能做任何事情。解决方案是为test.viz() 使用thread,而您的my_visual 类线程不再需要。

我在刷新前2秒添加了time.sleep使其变为蓝色,否则一开始颜色为蓝色。

给你:

import threading
from tkinter import *
import time

class color1:
    def __init__(self, color):
       self.color = color

    def change_col(self, new_color):
        self.color = new_color

    def pass_col(self):
        return(self)

class my_visual():

    def __init__(self, col1):
        self.col1 = col1

    def viz(self):
        self.root = Tk()
        btn1 = Button(self.root, text = 'Refresh', command = self.refresh)
        btn1.pack()
        frame = Frame(self.root, width = 100, height = 100, bg = self.col1.color)
        frame.pack()
        btn2 = Button(self.root, text = 'Close', command = self.exit)
        btn2.pack()
        self.root.mainloop()

    def refresh(self):
        self.root.quit()
        self.root.destroy()
        self.col1 = self.col1.pass_col()
        print("self.col1", self.col1, self.col1.color)
        self.viz()


    def exit(self):
        self.root.quit()
        self.root.destroy()

c = color1('RED')
test = my_visual(c)
t2 = threading.Thread(target = test.viz)
t2.start()

time.sleep(2)
print('Now you can change to blue when refreshing')
c.change_col('BLUE')

【讨论】:

  • 这真的很有帮助,我认为这是功能发展的方向。谢谢你的信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-14
  • 1970-01-01
  • 2017-04-24
  • 2014-01-27
  • 2010-12-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多