python - Tkinter Async Error...without multithreading? -
i've needed gui work python , stumbled on tkinter. part, it; it's clean , intuitive , brief. there is, however, 1 little sticking point me: crashes out of nowhere. program run 5 times in row , sixth time, halfway through freeze , error
tcl_asyncdelete: async handler deleted wrong thread
my efforts find solution problem, both on website , others, have multithreading, don't use multiple threads. not explicitly, anyway. suspect fact have timer in gui blame, have not been able figure out why error pops up, or indeed why infrequent.
what follows shortest tkinter program i've written. happens in of them, suspect problem easiest see here. , appreciated, don't point me toward solution without telling me how applies code, because assure you, have looked @ it, , either doesn't apply or didn't understand how did. don't mind having missed answer, i'm new tkinter (and multithreading in general) might need told more explicitly.
this code simulation of game show saw online. of can safely ignored, i'm pasting here because don't know error from.
import re tkinter import tk, frame, disabled, button, label, font, normal, ttk random import choice import winsound class question: def __init__(self, t, a, o): self.text = t.strip().capitalize() + "?" self.answer = a.strip().title() self.options = o self.firstisright = self.answer.lower() == self.options[0].lower() assert self.firstisright or self.answer.lower() == self.options[1].lower(), self def __eq__(self, other): return self.text == other.text def __repr__(self): return "{1} or {2}, {0}".format(self.text, self.options[0], self.options[1]) class application(frame): def __init__(self, master=none): self.setup() frame.__init__(self, master) self.grid() self.customfont = font.font(family="times new roman", size=30) self.createwidgets() def setup(self): self.questions = [] open("twentyone.txt",'r') file: line in file: groups = re.split("[,\.\?]",line) answers = re.split(" or ",groups[0]) self.questions.append(question(groups[1], groups[2], answers)) def createwidgets(self): self.gamepanel = frame(self) self.gamepanel.grid(column=0,row=0) self.displaypanel = frame(self) self.displaypanel.grid(column=0,row=1) self.buttonpanel = frame(self) self.buttonpanel.grid(column=0,row=2) self.quit = button(self.buttonpanel,text="quit",font=self.customfont,command=self.quit) self.quit.grid(row=0,column=2) self.begin = button(self.buttonpanel, text="begin",font=self.customfont, command = self.begin) self.begin.grid(row=0,column=0) self.stop = button(self.buttonpanel, text="stop",font=self.customfont, command = self.stop) self.stop.grid(row=0,column=1) self.stop["state"] = disabled self.title = label(self.gamepanel,text="21 questions wrong",font=self.customfont,bg="black",fg="white") self.title.grid(columnspan=2) self.questiontext = label(self.gamepanel,text="questions go here",font=self.customfont,wraplength=400) self.questiontext.grid(row=1,columnspan=2) self.leftchoice = button(self.gamepanel,text="option 1",font=self.customfont) self.leftchoice.grid(row=2,column=0) self.rightchoice = button(self.gamepanel,text="option 2",font=self.customfont) self.rightchoice.grid(row=2,column=1) self.timertext = label(self.displaypanel, text="150",font=self.customfont) self.timertext.grid(row=0) self.progress = ttk.progressbar(self.displaypanel, length=100,maximum=22) self.progress.grid(row=0,column=1,padx=10) def begin(self): self.timer(250) self.asked = [] self.stop["state"] = normal self.leftchoice["state"] = normal self.rightchoice["state"] = normal self.restart = false self.asknewquestion() def asknewquestion(self): if self.restart: self.currentquestion = self.asked[int(self.progress["value"])] else: self.currentquestion = choice([i in self.questions if not in self.asked]) self.asked.append(self.currentquestion) self.questiondisplay() def questiondisplay(self): self.questiontext["text"] = self.currentquestion.text self.leftchoice["text"] = self.currentquestion.options[0] self.rightchoice["text"] = self.currentquestion.options[1] if self.currentquestion.firstisright: self.leftchoice["command"] = self.correct self.rightchoice["command"] = self.wrong else: self.leftchoice["command"] = self.wrong self.rightchoice["command"] = self.correct def correct(self): self.progress.step() if self.progress["value"] >= 21: self.gameover(true, 21) else: if self.progress["value"] >= len(self.asked): self.restart = false self.asknewquestion() def wrong(self): self.restart = true self.progress["value"] = 0 winsound.beep(750,700) self.asknewquestion() def stop(self): self.after_cancel(self.timerafter) self.begin["state"] = normal self.stop["state"] = disabled def gameover(self, success, longest): self.after_cancel(self.timerafter) self.begin["state"] = normal self.stop["state"] = disabled self.questiontext["text"] = "congratulations!" if success else "too bad!" self.leftchoice["text"] = "game" self.leftchoice["state"] = disabled self.rightchoice["text"] = "over" self.rightchoice["state"] = disabled self.showpoints(success, longest) def showpoints(self, s, l): if s: timetaken = max(0, 100-int(self.timertext["text"])) print("you scored {0} points".format(1000-10*timetaken)) else: print("you scored no points") def timer(self, time): self.begin["state"] = disabled self.stop["state"] = normal self.runtimer(time) def runtimer(self, current=none, resume=false): if current not none: self.current = current self.timertext["text"] = self.current if self.current == 0: self.gameover(false, len(self.asked)-1) else: self.current -= 1 self.timerafter = self.after(1000,self.runtimer) root = tk() app = application(master=root) app.master.title("score calculator!") app.anchor("center") root.mainloop() root.destroy()
Comments
Post a Comment