Python 如何在mainloop()之后创建新的Tkinter窗口?
我想在屏幕上动态创建Tkinter窗口。我知道我应该只有一个主循环。我使用线程模块使mainloop在一个单独的线程中执行,因此它不会阻塞脚本 在执行mainloop之后,如何创建更多Tkinter窗口 请看一下我的代码:Python 如何在mainloop()之后创建新的Tkinter窗口?,python,tkinter,Python,Tkinter,我想在屏幕上动态创建Tkinter窗口。我知道我应该只有一个主循环。我使用线程模块使mainloop在一个单独的线程中执行,因此它不会阻塞脚本 在执行mainloop之后,如何创建更多Tkinter窗口 请看一下我的代码: from Tkinter import * import threading import time class box: def __init__(self, pos): self.master = Tk() self.master
from Tkinter import *
import threading
import time
class box:
def __init__(self, pos):
self.master = Tk()
self.master.geometry(pos)
self.canvas = Canvas(self.master, width=50, height=50, highlightthickness=0 )
self.canvas.pack()
self.rect = self.canvas.create_rectangle(0, 0, 50, 50, fill="red", outline="red")
self.text = self.canvas.create_text(25, 24, text="99",fill="white", font=("calibri", 24, "bold"))
def changeFill(self, color):
self.canvas.itemconfig(self.rect, fill=color, outline=color) # change color
class box_manager(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.boxes = {}
self.add_box(1, "50x50+300+300")
self.add_box(2, "50x50+100+100")
def add_box(self, num, pos):
self.boxes[num] = box(pos)
def run(self):
mainloop()
tk = box_manager()
tk.start()
# How do I dynamically add new tkinter windows? the line below makes python.exe crash.
tk.add_box(3, "50x50+200+200")
在Joel的评论后更新,仍然不起作用:
from Tkinter import *
import threading
import time
class MyCustomWindow(Toplevel):
def __init__(self):
Toplevel.__init__(self)
#setup goes here
self.geometry("50x50+100+100")
self.canvas = Canvas(self, width=50, height=50, highlightthickness=0 )
self.canvas.pack()
class App(Tk):
def CreateFirst(self):
self.anotherWindow = MyCustomWindow()
def CreateSecond(self):
self.secondWindow = MyCustomWindow()
class SecondWindow(threading.Thread):
#after 2 seconds create a second window, python.exe crashes
def run(self):
time.sleep(2)
tk.CreateSecond()
SecondWindow().start()
tk = App()
tk.CreateFirst()
mainloop()
在执行mainloop之后,如何创建更多Tkinter窗口
你没有。Tkinter不是这样设计的。您应该始终从主线程准确地调用mainloop一次 附加的非根窗口只是顶级小部件。您只需将Toplevel子类化,并从主类中调用它:
class MyCustomWindow(tkinter.Toplevel):
def __init__(self):
tkinter.Toplevel.__init__(self)
#setup goes here
class App(tkinter.Tk):
def someCallback(self):
self.anotherWindow = MyCustomWindow()
编辑
当然,您不必为Toplevel创建子类,您可以直接使用它 好的,但是我如何在运行中创建新的小部件呢?我在一个单独的线程中有一个循环,它监视打开的程序,并且应该为它看到的每个新程序创建一个新的对话框/小部件,就像某种覆盖一样。@koen:不能直接从单独的线程创建小部件。您必须将信息放入线程安全队列,然后让您的主GUI线程轮询队列并创建小部件。太好了,这非常有意义。我要试一试。谢谢你的帮助。我尝试了您的示例,但当我在运行mainloop之后在单独的线程中运行MyCustomWindow时,Python崩溃了。假设我想显示一个窗口,等待5秒钟,然后同时显示另一个窗口。我该怎么做?首先,你有多个根或主。任何给定的tkinter应用程序都应该只有一个Tk实例。其他一切都应该是这一个实例的产物。Joel,你能看看我在原始帖子中的新代码吗?我试着理解你的解释,我已经解决了。Mainloop现在在主线程中运行。主线程从python队列中读取数据。我有一个单独的线程,可以将新的顶级窗口添加到队列中。谢谢你的帮助。另请参阅上面Bryan的答案。你确定需要穿线吗?在一个线程中,你可以用Tkinter做很多事情。