Thread won't stop until window is destroyed, window won't destroy unless thread is stopped
Thread won't stop until window is destroyed, window won't destroy unless thread is stopped
所以我有一个 window,它由 运行 在后台的线程控制,并在必要时更改 GUI,在某些时候将指示该线程更改 window(涉及销毁它所在的 window 并启动另一个 window),但这永远不会发生,因为线程不会停止执行,直到 window 被更改。
下面是一个简化的例子:
class Window1:
def __init__(...):
self.Master = tk.Tk()
# some code
self.BackgroundUpdates = threading.Thread(target=self.ActiveWindow)
self.BackgroundUpdates.start()
def ActiveWindow(self):
# gets some instruction
if instruction == 'next window':
nextWindow(self)
def StartWindow(self):
self.Master.mainloop()
def KillWindow(self):
self.Master.destroy()
class Window2:
def __init__(...):
self.Master = tk.Tk()
# some code...
def StartWindow(self):
self.Master.mainloop()
def nextWindow(objectWindow):
objectWindow.KillWindow()
# when this function is called it never gets past the line above
nextWindow = Window2()
nextWindow.StartWindow()
application = Window1()
application.StartWindow()
有没有一种方法可以重新安排我处理线程的方式,这样我就不会 运行 遇到这个问题?
一个运行可用的例子:
import tkinter as tk
import threading
class MainWindow:
def __init__(self):
self.Master = tk.Tk()
self.Frame = tk.Frame(self.Master, width=100, height=100)
self.Frame.pack()
self.Updates = threading.Thread(target=self.BackgroundUpdates)
self.Updates.start()
def BackgroundUpdates(self):
# imagine instructions to be a really long list with each element being a
# different instruction
instructions = ['instruction1', 'instruction2', 'next window']
while True:
if instructions[0] == 'next window':
ChangeWindow(self)
else:
instructions.remove(instructions[0])
def StartWindow(self):
self.Master.mainloop()
def KillWindow(self):
self.Master.destroy()
class SecondaryWindow:
def __init__(self):
self.Master = tk.Tk()
self.Frame = tk.Frame(self.Master, width=100, height=100)
self.Frame.pack()
def StartWindow(self):
self.Master.mainloop()
def KillWindow(self):
self.Master.destroy()
def ChangeWindow(oldObject):
oldObject.KillWindow()
# the line above will halt the program, since it has to wait on the thread to
# finish before the window can be destroyed, but this function is being called
# from within the thread and so the thread will never stop executing
del oldObject
newObject = SecondaryWindow()
newObject.StartWindow()
window = MainWindow()
window.StartWindow()
我意识到tkinter是单线程的,可以在这里解释更多:
问题是我试图将我的 window 从另一个线程销毁到创建它的线程。为了解决这个问题,我不得不使用 Tkinter 中的 'after' 方法模块以及使用事件,这意味着我可以控制后台的东西(即等待来自我连接的服务器的特定命令)并且当我需要更改 window 我会设置事件。
下面是我改编的部分代码:
def CheckEvent(self):
if LOBBY_EVENT.is_set():
ChangeWindow(self, 'game')
self.Master.after(5000, self.CheckEvent)
def StartWindow(self):
self.Master.after(5000, self.CheckEvent)
self.Master.after(2000, self.HandleInstruction)
self.Master.mainloop()
所以每当我为 window 调用 StartWindow 方法时,它会每 5 秒检查一次事件是否已设置,然后每 2 秒它会转到一个单独的函数 'HandleInstruction' 这允许我在我的 GUI 中创建一个响应(我还使用队列将信息传递给这个函数)
如果有人偶然发现它,我希望这能消除困惑!
所以我有一个 window,它由 运行 在后台的线程控制,并在必要时更改 GUI,在某些时候将指示该线程更改 window(涉及销毁它所在的 window 并启动另一个 window),但这永远不会发生,因为线程不会停止执行,直到 window 被更改。
下面是一个简化的例子:
class Window1:
def __init__(...):
self.Master = tk.Tk()
# some code
self.BackgroundUpdates = threading.Thread(target=self.ActiveWindow)
self.BackgroundUpdates.start()
def ActiveWindow(self):
# gets some instruction
if instruction == 'next window':
nextWindow(self)
def StartWindow(self):
self.Master.mainloop()
def KillWindow(self):
self.Master.destroy()
class Window2:
def __init__(...):
self.Master = tk.Tk()
# some code...
def StartWindow(self):
self.Master.mainloop()
def nextWindow(objectWindow):
objectWindow.KillWindow()
# when this function is called it never gets past the line above
nextWindow = Window2()
nextWindow.StartWindow()
application = Window1()
application.StartWindow()
有没有一种方法可以重新安排我处理线程的方式,这样我就不会 运行 遇到这个问题?
一个运行可用的例子:
import tkinter as tk
import threading
class MainWindow:
def __init__(self):
self.Master = tk.Tk()
self.Frame = tk.Frame(self.Master, width=100, height=100)
self.Frame.pack()
self.Updates = threading.Thread(target=self.BackgroundUpdates)
self.Updates.start()
def BackgroundUpdates(self):
# imagine instructions to be a really long list with each element being a
# different instruction
instructions = ['instruction1', 'instruction2', 'next window']
while True:
if instructions[0] == 'next window':
ChangeWindow(self)
else:
instructions.remove(instructions[0])
def StartWindow(self):
self.Master.mainloop()
def KillWindow(self):
self.Master.destroy()
class SecondaryWindow:
def __init__(self):
self.Master = tk.Tk()
self.Frame = tk.Frame(self.Master, width=100, height=100)
self.Frame.pack()
def StartWindow(self):
self.Master.mainloop()
def KillWindow(self):
self.Master.destroy()
def ChangeWindow(oldObject):
oldObject.KillWindow()
# the line above will halt the program, since it has to wait on the thread to
# finish before the window can be destroyed, but this function is being called
# from within the thread and so the thread will never stop executing
del oldObject
newObject = SecondaryWindow()
newObject.StartWindow()
window = MainWindow()
window.StartWindow()
我意识到tkinter是单线程的,可以在这里解释更多:
问题是我试图将我的 window 从另一个线程销毁到创建它的线程。为了解决这个问题,我不得不使用 Tkinter 中的 'after' 方法模块以及使用事件,这意味着我可以控制后台的东西(即等待来自我连接的服务器的特定命令)并且当我需要更改 window 我会设置事件。
下面是我改编的部分代码:
def CheckEvent(self):
if LOBBY_EVENT.is_set():
ChangeWindow(self, 'game')
self.Master.after(5000, self.CheckEvent)
def StartWindow(self):
self.Master.after(5000, self.CheckEvent)
self.Master.after(2000, self.HandleInstruction)
self.Master.mainloop()
所以每当我为 window 调用 StartWindow 方法时,它会每 5 秒检查一次事件是否已设置,然后每 2 秒它会转到一个单独的函数 'HandleInstruction' 这允许我在我的 GUI 中创建一个响应(我还使用队列将信息传递给这个函数)
如果有人偶然发现它,我希望这能消除困惑!