在我的程序中,我实现了一个弹出窗口,其中包含一些供用户输入的条目。该弹出窗口具有“输入”按钮,以确认并收集输入,然后自动关闭弹出窗口。
为了关闭弹出窗口,我找到了root.destroy()
和root.quit()
方法(在我的代码self.master中而不是root中)。我以为我有点了解如何使用它们,但显然我没有。 :/
import tkinter as tk
root = tk.Tk()
window = MainWindow(root)
root.mainloop()
class MainWindow(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
self.pack()
#some irrelevant widgets
btn_new_element = tk.Button(self, text='new', command=self.new_element)
btn_new_element.pack()
def new_element(self):
root = tk.Toplevel()
popup = Pupup(root, someData, otherData)
root.mainloop()
#do some other stuff
class Popup(tk.Frame):
def __init__(self, master, var1, var2):
tk.Frame.__init__(self, master)
self.pack()
#some widgets
btn = tk.Button(self, text='Enter', command=lambda a=var1, b=var2: self.foo(a, b))
btn.pack()
def foo(self, a, b):
#do something with widget data
self.master.quit()
self.master.destroy()
首先在foo()
中,我只使用了destroy()
。它关闭了弹出窗口,但是程序没有继续执行new_element()
中的代码。 (似乎mainloop()
仍在循环。)
使用quit()
会产生相反的结果:new_element()
中的其余代码已执行,但Popup仍然存在。
仅按照特定顺序使用quit()
和destroy()
可以得到我想要的结果。
根据Internet上的数千个示例,应该仅可以使用两种方法之一。为什么在我的代码中不起作用?
编辑:从MainWindow构造函数中删除了var1和var2(在创建此问题期间复制并粘贴错误。
编辑:我也感觉到问题可能出在根杂草丛的范围上。在new_element()
中创建一个名为root的局部变量还是覆盖全局根变量?
答案 0 :(得分:2)
问题的根源在于您多次致电mainloop
。你不应该那样做。它会引起很多问题,就像您遇到的问题一样。
如果您的目标是创建一个弹出窗口,然后等待用户关闭弹出窗口,则tkinter有专门用于此的方法。它称为wait_window
,直到它正在等待的窗口被销毁,它才会返回。
top = tk.Toplevel()
popup = Popup(top, "some data", "other data")
top.wait_window(top)
您可以在top.wait_window(top)
之后放置其他代码,直到弹出窗口销毁后,该代码才会执行。
在您的弹出代码中,您的按钮只需要在弹出窗口中调用destroy
。您不应致电quit
。
def foo(self, a, b):
#do something with widget data
self.master.destroy()
答案 1 :(得分:0)
您的示例有很多问题(复制粘贴不起作用),但是在安排了一些事情(赋予值和东西)后,这就是您的问题:
def new_element(self):
root = tk.Toplevel()
popup = Pupup(root, someData, otherData)
# root.mainloop() # < ------ This generates a new main loop, with is destroyed.
这是有效的完整代码:
import tkinter as tk
class Popup(tk.Frame):
def __init__(self, master, var1, var2):
tk.Frame.__init__(self, master)
self.pack()
#some widgets
btn = tk.Button(self, text='Enter', command=lambda a=var1, b=var2: self.foo(a, b))
btn.pack()
def foo(self, a, b):
#do something with widget data
self.master.quit()
# self.master.destroy()
class MainWindow(tk.Frame):
def __init__(self, master, var1, var2):
tk.Frame.__init__(self, master)
self.pack()
#some irrelevant widgets
btn_new_element = tk.Button(self, text='new', command=self.new_element)
btn_new_element.pack()
def new_element(self):
root = tk.Toplevel()
popup = Popup(root, 'a', 'b')
# root.mainloop()
#do some other stuff
root = tk.Tk()
window = MainWindow(root,1,2)
root.mainloop()
答案 2 :(得分:0)
我相信问题是您创建了第二个循环,要解决此问题,您只需删除第二个循环,然后.destroy()
函数就可以正常工作。
赞
class MainWindow(tk.Frame):
def __init__():
# your init code
def new_element(self):
root = tk.Toplevel()
popup = Popup(root, 1, 0)
class Popup(tk.Frame):
def __init__(self, master, var1, var2):
# your init code
def foo(self, a, b):
self.master.destroy()
我将要发表的另一条评论是,我认为您构造此窗口的方式具有误导性,并且可能引起混乱(请记住,这只是偏好设置,不再涉及“实际”问题)。
我相信您应该创建一个Popup(Frame)
类,而不要使用Popup(Toplevel)
类。
赞
import tkinter as tk
class MainWindow(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
self.pack()
btn_new_element = tk.Button(self, text='new', command=self.new_element)
btn_new_element.pack()
self.master = master
self.pack()
def new_element(self):
popup = Popup(self.master, 1, 0)
class Popup(tk.Toplevel):
def __init__(self, master, var1, var2):
super().__init__(master)
#some widgets
btn = tk.Button(self, text='Enter', command=lambda a=var1, b=var2: self.foo(a,b))
btn.pack()
def foo(self, a, b):
self.destroy()
if __name__ == '__main__':
root = tk.Tk()
window = MainWindow(root)
root.mainloop()
创建顶级元素时,它需要一个母版,在此实例中,母版将成为主窗口。当您在Toplevel类中使用self.destroy时,您不是在破坏Toplevels主机,而是在破坏Toplevel本身。