我正在尝试创建一个程序,允许用户从晦涩的名字列表中输入人的真实姓名。
我希望从主根窗口生成弹出窗口。一旦用户输入了真实姓名,弹出窗口应该关闭,然后打开列表中的下一个模糊名称。
我还希望用户能够通过关闭主根窗口来终止整个迭代;因此需要它而不是为每个名称创建单独的弹出窗口。
我尝试过使用win.destroy(),这会杀死第一个弹出窗口,但迭代也会被终止,第二个名称也不会被打开。然后我尝试使用win.quit(),但这会打开弹出窗口,如果输入两次信息则会导致程序崩溃。
在不中断迭代的情况下分配真实姓名后,是否可以关闭弹出窗口?
这是我的代码(我已经包含了我尝试过的win.quit()和win.destroy()命令)
from Tkinter import *
name_list = ["Jimmy Bob", " Bobby Jim", "Sammy Jim Bob" ]
def assign():
print("You chose option %s" %(e1.get()))
win.destroy() # Ends the iteration
#win.quit() # Continues the iteration but does not close the window and crashes if entered twice
root = Tk()
for i in name_list:
win = Toplevel(root)
win.lift()
e1 = Entry(win)
e1.grid(row=1, column=0)
var = StringVar()
var.set(i)
Label(win, textvariable = var).grid(row=0, column=0)
Button(win, text='Enter Real Name', command=assign).grid(row=2, column=0, pady=4)
win.mainloop( )
root.mainloop()
答案 0 :(得分:0)
问题在于win.mainloop()
正在阻塞,因此在迭代中使用它意味着在胜利关闭之前不会发生任何事情。
然而,只是摆脱win.mainloop()
导致所有的弹出窗口立即出现,所以我们需要一种方法来使它只有按下按钮才会发生下一次迭代,这就是原因对于do_next()
函数
我做的最后一个更改是添加了quit
函数,这复制了在早期版本中关闭root
窗口的行为,方法是让每个弹出窗口都有一个退出方式,因为除非按下按钮,否则它不会运行do_next()
。
from Tkinter import *
name_list = ["Jimmy Bob", " Bobby Jim", "Sammy Jim Bob" ]
def assign():
global e1, win
print("You chose option %s" %(e1.get()))
win.destroy()
do_next()
def quit():
global root
root.destroy()
def do_next():
global i, e1, win, root
if i == len(name_list):
root.destroy()
return
win = Toplevel(root)
win.lift()
e1 = Entry(win)
e1.grid(row=1, column=0)
var = StringVar()
var.set(name_list[i])
Label(win, textvariable = var).grid(row=0, column=0)
Button(win, text='Enter Real Name', command=assign).grid(row=2, column=0, pady=4)
win.protocol("WM_DELETE_WINDOW",quit)
i += 1
i = 0
root = Tk()
root.withdraw()
do_next()
root.mainloop()
其他一些需要注意的事项:如果您将此作为更大脚本的一部分包含在内,我会将整个弹出过程封装在专门的类中,以避免使用全局变量