Reputation: 1
I have created a mad libs program and the window shows up as just an empty GUI and after I shut it down the tkinter code comes up saying that tk has no attribute. Here is my Program.
from tkinter import *
class Application(Frame):
'''GUI that takes a user's input in order to create a story'''
def initializeFrame(self, master):
'''Initializes the frame'''
#superclass constructor
super(Application, self).initializeFrame(master)
self.grid()
self.createWidgets()
def createWidgets(self):
'''Creates some widgets that get the information of the story and display it'''
#instruction label
Label(self,
text = "Enter story information"
).grid(row = 0, column = 0, columnspan = 2, sticky = W)
Label(self,
text = "Person: "
).grid(row = 1, column = 0, sticky = W)
self.personEntry = Entry(self)
self.PersonEntry.grid(row = 1, column = 1, sticky = W)
Label(self,
text = "Plural Noun:"
).grid(row = 2, column = 0, sticky = W)
self.nounEntry = Entry(self)
self.nounEntry.grid(row = 2, column = 1, sticky = W)
Label(self,
text = "Verb:"
).grid(row = 3, column = 0, sticky = W)
self.verbEntry = Entry(self)
self.verbEntry.grid(row = 3, column = 1, sticky = W)
Label(self,
text = "Adjective:"
).grid(row = 4, column = 0, sticky = W)
self.isItchy = BooleanVar()
Checkbutton(self,
text = "itchy",
variable = self.isItchy
).grid(row = 4, column = 1, sticky = W)
self.isJoyous = BooleanVar()
Checkbutton(self,
text = "joyous",
variable = self.isJoyous
).grid(row = 4, column = 2, sticky = W)
self.isElectric = BooleanVar()
Checkbutton(self,
text = "electric",
variable = self.isElectric
).grid(row = 4, column = 3, sticky = W)
Label(self,
text = "Body Part:"
).grid(row = 5, column = 0, sticky = W)
self.bodyPart = StringVar()
self.bodyPart.set(None)
bodyParts = ["gluteus maximus", "platella", "Cranium"]
column = 1
for part in bodyParts:
Radiobutton(self,
text = part,
variable = self.bodyPart,
value = part
).grid(row = 5, column = column, sticky = W)
column += 1
Button(self,
text = "Click for the story",
command = self,
).grid(row = 6, column = 0, sticky = W)
self.storyTxt = Text(self, width = 75, height = 10, wrap = WORD)
self.storyTxt.grid(row = 7, column = 0, columnspan = 4)
def tellStory(self):
'''Prints the new story based on the users inputs'''
person = self.personEntry.get()
noun = self.nounEntry.get()
verb = self.verbEntry.get()
adjectives = ""
if self.isItchy.get():
adjectives +='itchy, '
if self.isJoyous.get():
adjectives += 'itchy, '
if self.isElectric.get():
adjectives += 'electric, '
bodyPart = self.bodyPart.get()
#the story
story = "The famous explorer"
story += person
story = "had nearly given up on a life-long quest to find The Lost City of"
story += noun.title()
story = "when one day, the"
story += noun
story += "found"
story += person + "."
story += "A strong"
story += adjectives
story += "peculiar feeling overwhelmed the explorer. "
story += "After all this time, the quest was finally over. A tear came to "
story += person + "'s"
story += bodyPart + ". "
story += "And then, the "
story += noun
story += "promptly devoured "
story += person + "."
story += "The moral of this story? Be careful what you "
story += verb
story += "for. "
self.storyTxt.delete(0.0, END)
self.storyTxt.insert(0.0, story)
root = Tk()
root.title("Mad Libs")
app = Application(root)
root.mainloop()
Application(Frame)
createWidgets(self)
And here is the part of the tkinter program that has an error
class BaseWidget(Misc):
"""Internal class."""
def _setup(self, master, cnf):
"""Internal function. Sets up information about children."""
if _support_default_root:
global _default_root
if not master:
if not _default_root:
_default_root = Tk()
master = _default_root
self.master = master
self.tk = master.tk
name = None
if 'name' in cnf:
name = cnf['name']
del cnf['name']
if not name:
name = repr(id(self))
self._name = name
if master._w=='.':
self._w = '.' + name
else:
self._w = master._w + '.' + name
self.children = {}
if self._name in self.master.children:
self.master.children[self._name].destroy()
self.master.children[self._name] = self
def __init__(self, master, widgetName, cnf={}, kw={}, extra=()):
"""Construct a widget with the parent widget MASTER, a name WIDGETNAME
and appropriate options."""
if kw:
cnf = _cnfmerge((cnf, kw))
self.widgetName = widgetName
BaseWidget._setup(self, master, cnf)
if self._tclCommands is None:
self._tclCommands = []
classes = [(k, v) for k, v in cnf.items() if isinstance(k, type)]
for k, v in classes:
del cnf[k]
self.tk.call(
(widgetName, self._w) + extra + self._options(cnf))
for k, v in classes:
k.configure(self, v)
def destroy(self):
"""Destroy this and all descendants widgets."""
for c in list(self.children.values()): c.destroy()
self.tk.call('destroy', self._w)
if self._name in self.master.children:
del self.master.children[self._name]
Misc.destroy(self)
def _do(self, name, args=()):
# XXX Obsolete -- better use self.tk.call directly!
return self.tk.call((self._w, name) + args)
Upvotes: 0
Views: 686
Reputation: 385890
This is not a bug in tkinter, it is a bug in your code.
root.mainloop()
needs to be the last line of code executed in your program. It will not return ultil the main window is destroyed. You have code after that which tries to create more windows. Since the main window has been destroyed, you get the error that you report.
Your window is likely coming up blank because you call self.createWidgets
but that class has no such method. Perhaps this is a typo in your code, since you do define a function with that name, but outside the scope of the class.
Upvotes: 1