0

I am attempting to make a simple Tkinter script that takes three variables (first name, last name, company) and generates a few email possibilities.

Here is my code:

from Tkinter import *

class Application(Frame):

        def __init__(self, master):
            Frame.__init__(self, master)
            self.grid()
            self.create_widgets()

        def create_widgets(self):
            self.firstname = Entry(self, text="First")
            self.firstname.grid(row= 0, column = 0, columnspan = 2, sticky = W)
            self.firstname.insert(0, "First Name")

            self.lastname = Entry(self)
            self.lastname.grid(row= 1, column = 0, columnspan = 2, sticky = W)
            self.lastname.insert(0, "Last Name")


            self.companyname = Entry(self)
            self.companyname.grid(row= 2, column = 0, columnspan = 2, sticky = W)
            self.companyname.insert(0, "Company Name")

            self.button = Button(self, text="Generate!", command=self.gen_email(self.firstname.get(),self.lastname.get(),self.companyname.get()))
            self.button.grid()

            #where the generated emails will go
            self.text = Text(self, width = 35, height=5, wrap =WORD)
            self.text.grid(row=4,column=0, columnspan=2, sticky=W)


        def gen_email(self, firstname, lastname, companyname):
            self.email_list = []
            self.email_list.append(firstname + "." + lastname + "@" + companyname + ".com")
            self.email_list.append(firstname[0] + lastname + "@" + companyname + ".com")
            self.email_list.append(firstname + lastname[0] + "@" + companyname + ".com")
            self.email_list.append(firstname + "@" + companyname + ".com")
            self.email_list.append(firstname + "_" + lastname +"@" + companyname + ".com")

            self.text.insert(0.0, self.email_list) 




root = Tk()
root.title("Email Generator")
root.geometry("400x400")

app = Application(root)
root.mainloop()

I am getting an error message when trying to display the generated email on the screen:

 Traceback (most recent call last):
  File "emailgen.py", line 65, in <module>
    app = Application(root)
  File "emailgen.py", line 21, in __init__
    self.create_widgets()
  File "emailgen.py", line 39, in create_widgets
    self.button = Button(self, text="Generate!", command=self.gen_email(self.firstname.get(),self.lastname.get(),self.companyname.get()))
  File "emailgen.py", line 56, in gen_email
    self.text.insert(0.0, self.email_list) 
AttributeError: Application instance has no attribute 'text'

I am getting an error here: self.text.insert(0.0, self.email_list), yet self.text is defined within the program and has been added to the grid. How can I make this functionality work, as it seems I am missing something here.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
ApathyBear
  • 9,057
  • 14
  • 56
  • 90
  • 1
    Please see e.g. http://stackoverflow.com/q/8269096/3001761; `self.text` **has not** been defined when the function is called, because you supply the `command` incorrectly. The easiest thing is probably to move the `.get()`s into `gen_email`. – jonrsharpe Feb 19 '15 at 23:07

1 Answers1

2

You need to provide lambda for the buttons command:

    self.button = Button(self, text="Generate!", 
                         command=lambda :self.gen_email(self.firstname.get(),
                                                self.lastname.get(),
                                                self.companyname.get()))

A better way would be to have self.firstname.get(), self.lastname.get(), self.companyname.get() in your gen_email function. This way you could eliminate lambda:

from Tkinter import *

class Application(Frame):

        def __init__(self, master):
            Frame.__init__(self, master)
            self.grid()
            self.create_widgets()

        def create_widgets(self):
            self.firstname = Entry(self, text="First")
            self.firstname.grid(row= 0, column = 0, columnspan = 2, sticky = W)
            self.firstname.insert(0, "First Name")

            self.lastname = Entry(self)
            self.lastname.grid(row= 1, column = 0, columnspan = 2, sticky = W)
            self.lastname.insert(0, "Last Name")


            self.companyname = Entry(self)
            self.companyname.grid(row= 2, column = 0, columnspan = 2, sticky = W)
            self.companyname.insert(0, "Company Name")

            self.button = Button(self, text="Generate!", 
                                 command=self.gen_email)
            self.button.grid()

            #where the generated emails will go
            self.text = Text(self, width = 35, height=5, wrap =WORD)
            self.text.grid(row=4,column=0, columnspan=2, sticky=W)


        def gen_email(self):
            firstname = self.firstname.get()
            lastname =  self.lastname.get()
            companyname =  self.companyname.get()
            self.email_list = []
            self.email_list.append(firstname + "." + lastname + "@" + companyname + ".com")
            self.email_list.append(firstname[0] + lastname + "@" + companyname + ".com")
            self.email_list.append(firstname + lastname[0] + "@" + companyname + ".com")
            self.email_list.append(firstname + "@" + companyname + ".com")
            self.email_list.append(firstname + "_" + lastname +"@" + companyname + ".com")

            self.text.insert(0.0, self.email_list) 




root = Tk()
root.title("Email Generator")
root.geometry("400x400")

app = Application(root)
root.mainloop()
Marcin
  • 215,873
  • 14
  • 235
  • 294
  • A better solution would be to have a method dedicated to the button, so you don't need to use lambda. Call a function that does the `get`'s and calls `gen_email`. – Bryan Oakley Feb 19 '15 at 23:23
  • Yep. But I did not want to rewrite to much OP code and keep changes to minimum. – Marcin Feb 19 '15 at 23:35
  • I'd really like to know the better way to do this, instead of using lambda, for next time at least. If you could provide an example that would be awesome. – ApathyBear Feb 19 '15 at 23:39