【问题标题】:Bizarre quit behavior of thread with tkintertkinter 线程的奇怪退出行为
【发布时间】:2017-05-04 14:36:09
【问题描述】:

我正在尝试使用线程来创建并发执行的任务的 GUI 应用程序。代码如下:

from tkinter import *
from threading import *
import time
kill = False

def mainer():
    global kill
    while not kill:
        maintext.set(value='bbb')


def quitfunc():
    global kill
    kill = True
    time.sleep(2)
    root.destroy()



root=Tk()
maintext=StringVar(value='aaa')
Thread(target=mainer).start()
root.protocol("WM_DELETE_WINDOW", quitfunc)
root.mainloop()

问题:

  1. 就目前而言,在关闭根窗口时,进程不会停止。它继续运行。即使我为mainer 线程添加了一个无限循环来打印isalive(),它也会一直显示True为什么不退出?
  2. 如果我在mainer 函数中添加print(kill) 语句,我会得到以下两种结果之一:
    1. 如果写在maintext.set() 语句上方,在退出窗口时,打印停止执行,但线程仍然没有退出。非常罕见,它确实如此,我假设这必须取决于执行退出函数时函数所在的行。
    2. 如果写在该语句下方,则在退出时,线程几乎不可避免地会退出。

我不知道这里发生了什么。任何帮助表示赞赏。

【问题讨论】:

  • 您是否尝试在循环中添加time.sleep()?也许,只是也许,线程太忙于向 tkinter 发送命令。
  • @Jean-FrançoisFabre 我想了解行为背后的逻辑。为什么有必要这样做?而且实际项目需要从USB串口读取,time.sleep()不会造成延迟吗?
  • @Jean-FrançoisFabre 在这种情况下,无论我将print(kill 语句放在哪里,我都应该得到相同的结果?
  • 这让我想起了一些事情:我认为从线程执行 GUI 操作是不安全的。我不知道 tkinter,但 wxWidgets 有一个 callAfter 方法,它要求主线程执行操作。在子线程中执行操作会导致未定义的行为

标签: python multithreading python-3.x debugging tkinter


【解决方案1】:

如果你让线程成为守护进程,它会在主线程死掉时死掉,所以你根本不需要任何退出逻辑:

from tkinter import *
from threading import *
import time

def mainer():
    while True:
        maintext.set(value='bbb')
    time.sleep(.1) # just so my CPU does not rail

root=Tk()
maintext=StringVar(value='aaa')
t = Thread(target=mainer)
t.daemon = True
t.start()
root.mainloop()

【讨论】:

  • 方法仍然有效
猜你喜欢
  • 2021-03-24
  • 1970-01-01
  • 2018-03-06
  • 1970-01-01
  • 1970-01-01
  • 2015-01-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多