TKinter,Python - 使用迭代创建TopLevel弹出窗口,然后在不杀死root的情况下再次关闭它们

时间:2016-08-18 10:02:27

标签: python python-2.7 tkinter

我正在尝试创建一个程序,允许用户从晦涩的名字列表中输入人的真实姓名。

我希望从主根窗口生成弹出窗口。一旦用户输入了真实姓名,弹出窗口应该关闭,然后打开列表中的下一个模糊名称。

我还希望用户能够通过关闭主根窗口来终止整个迭代;因此需要它而不是为每个名称创建单独的弹出窗口。

我尝试过使用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()

1 个答案:

答案 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()

其他一些需要注意的事项:如果您将此作为更大脚本的一部分包含在内,我会将整个弹出过程封装在专门的类中,以避免使用全局变量