user3529049
user3529049

Reputation: 1

Tkinter bug with Python 3.3.3

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

Answers (1)

Bryan Oakley
Bryan Oakley

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

Related Questions