Tkinter:按钮打开另一个窗口(并关闭当前窗口)

时间:2013-02-23 15:49:05

标签: python graphics tkinter

我正在创建一个“定义测试”类型的程序(用户输入单词,词性和每个单词的同义词,然后程序根据所述信息对用户进行测验)。 在最后一个窗口(测验窗口)中,我有一个像这样的窗口布局:

1/25 What is the definition of _word_? # number out of total + prompt
Definition: _entry_ # entry fields for information
Part of Speech: _entry_
Next Help Quit # buttons; 'Next' checks the info and goes to the next word 
# 'Help' shows the info and goes to the next word
# 'Quit' force-quits the program
Tries Left: 5 # how many tries before the info is shown

我遇到的问题是“帮助”按钮。通常,只需输入错误信息5次,就会成功创建“帮助”窗口;然而,它仍保留原始单词(无法回答的单词),打开。当这个新窗口关闭时,新单词会出现,但会有两个窗口:新单词+旧单词。此外,“帮助”按钮本身会引发错误:

>>> 

Traceback (most recent call last):
  File _filepath_, line 455, in <module>
    main()
  File _filepath_, line 68, in main
    test(screenDim, test_dict)
  File _filepath_, line 451, in test
    root.destroy()
  File "C:\Python2.7.3\lib\lib-tk\Tkinter.py", line 1728, in destroy
    self.tk.call('destroy', self._w)
TclError: can't invoke "destroy" command:  application has been destroyed

这是我的test函数(我修剪了一些代码,以便更容易找到问题):

def test(screenDim, test_dict):
    class TestWords:
        def __init__(self, master):
            w, h = screenDim[0], screenDim[1]
            rootW, rootH, xPos, yPos = int(float(w)/3), int(float(h)/4), w/2 - (w/6), h/2 - (h/8)
            self.frame = Frame(master)
            self.frameB = Frame(self.frame)
            self.frameE = Frame(self.frame)
            self.posE = Entry(self.frameE, width = 50, justify = CENTER)
            self.defE = Entry(self.frameE, width = 50, justify = CENTER)
            self.posE.grid(row = 1, column = 2, pady = 5)
            self.defE.grid(row = 2, column = 2, pady = 5)
            # there are a few other widgets/frames that don't pertain to this problem
            self.goButton = Button(self.frameB, text = 'Next', command = self.getInfo, width = 10)
            self.helpButton = Button(self.frameB, text = 'Help', command = self.getHelp, width = 10)
            self.quitButton = Button(self.frameB, text = 'Quit', command = self.quitBox, width = 10, fg = 'red')
            self.goButton.grid(row = 1, column = 1, padx = 10)
            self.helpButton.grid(row = 1, column = 2, padx = 10)
            self.quitButton.grid(row = 1, column = 3, padx = 10)
            master.geometry("%sx%s+%s+%s" % (rootW, rootH, xPos, yPos))
            self.frameE.grid(row = 3, pady = 5)
            self.frameB.grid(row = 4, padx = rootW/4 - 60, pady = 5)
            self.frame.grid()
        def quitBox(self):
            import sys
            sys.exit('Program Terminated.')
        def getHelp(self):
            triesLeft = 0
            self.frame.quit()
            root.destroy()
        def getInfo(self):
            info = (self.posE.get(), self.defE.get())
            self.frame.quit()
            return info
    class GetHelp:
        def __init__(self, master):
            w, h = screenDim[0], screenDim[1]
            rootW, rootH, xPos, yPos = int(float(w)/4), int(float(h)/4), w/2 - (w/8), h/2 - (h/8)
            self.frame = Frame(master)
            self.frameB = Frame(self.frame)
            self.goButton = Button(self.frameB, text = 'Next', command = self.frame.quit, width = 10)
            self.quitButton = Button(self.frameB, text = 'Quit', command = self.quitBox, fg = 'red', width = 10)
            self.goButton.grid(row = 1, column = 1, padx = 5)
            self.quitButton.grid(row = 1, column = 2, padx = 5)
            self.frameB.grid(row = 2, padx = rootW/4 - 20, pady = 5)
            master.geometry("%sx%s+%s+%s" % (rootW, rootH, xPos, yPos))
            self.frame.grid()
            # again, a few widgets were removed for brevity
        def quitBox(self):
            import sys
            sys.exit('Program Terminated.')
    n, words, reviewWords = len(test_dict.keys()), test_dict.keys(), []
    shuffle(words)
    for i in range(n):
        word, triesLeft = words[i], 4
        while triesLeft >= 0:
            root = Tk(className = ' Definition Tester')
            root.columnconfigure(0, weight=1)
            root.rowconfigure(0, weight=1)
            app = TestWords(root)
            root.mainloop()
            try:
                info = app.getInfo()
            except TclError:
                info = ('', '')
            if info[0] == test_dict[word][0] and info[1] in test_dict[word][1]:
                del words[i]
                root.destroy()
                break
            elif triesLeft == 0:
                reviewWords.append(word)
                root = Tk(className = ' Definition Tester')
                root.columnconfigure(0, weight=1)
                root.rowconfigure(0, weight=1)
                app = GetHelp(root)
                root.mainloop()
                break
            else:
                triesLeft -= 1
                root.destroy()

程序在剩余0次尝试后自动显示帮助窗口。因此,“帮助”按钮将triesLeft设置为0.但是,这似乎不会打开窗口。谢谢!

2 个答案:

答案 0 :(得分:2)

您需要重新构建解决方案,以便只创建一个根窗口,并且只运行mainloop的单个实例。不是一遍又一遍地创建和销毁根窗口,而是创建和销毁Toplevel的实例。 Tkinter根本不是为了创建和销毁多个根窗口而设计的。

答案 1 :(得分:0)

您必须更改tkinter变量并退出函数中的当前窗口,然后打开另一个

def new_window():
    current_tkinter_variable.quit()
    new_variable=Tk()
    #carry on