我正在创建一个“定义测试”类型的程序(用户输入单词,词性和每个单词的同义词,然后程序根据所述信息对用户进行测验)。 在最后一个窗口(测验窗口)中,我有一个像这样的窗口布局:
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.但是,这似乎不会打开窗口。谢谢!
答案 0 :(得分:2)
您需要重新构建解决方案,以便只创建一个根窗口,并且只运行mainloop
的单个实例。不是一遍又一遍地创建和销毁根窗口,而是创建和销毁Toplevel
的实例。 Tkinter根本不是为了创建和销毁多个根窗口而设计的。
答案 1 :(得分:0)
您必须更改tkinter变量并退出函数中的当前窗口,然后打开另一个
def new_window():
current_tkinter_variable.quit()
new_variable=Tk()
#carry on