1

I'm creating an interface that first prompts the user to login to the database. I'm having trouble with the get method for an Entry object. For the 'Login' button command, I use lambda since I am calling the login function which takes arguments. Since I'm passing Entry objects into my login function I call user.get() and pw.get() in those functions.

Upon running this code however, it says that user.get(), pw.get() are Nonetype objects with no attribute get. I don't understand why the entries are Nonetype since the logintoDB should be called after the buttons are created.

Thanks for the help.

Below is my code:

import Tkinter as tk
import tkFileDialog as tkfd
import tkMessageBox as tkmb
import xlrd

def openFile():
    #returns an opened file
    fname = tkfd.Open(filetypes = [("xls files","*.xls")])
    fpath = fname.show()
    if fname:
        try:
            TLA_sheet = xlrd.open_workbook(fpath).\
                    sheet_by_name('TLA - TOP SKUs')
            tk.Button(root, text = "Import TLAs", command = lambda: importTLAtoDB(TLA_sheet)).pack()
        tkmb.showinfo("Success!", "Spreadsheet successfully loaded. \n\
        Click Import TLAs to load TLA info into RCKHYVEDB database.")
        except:
            tkmb.showerror("Error", "Failed to read file\n '%s'\n\
            Make sure file is a type .xls" % fpath)

def enter(event):
    return logintoDB

def logintoDB(user, pw):
    #request login for database access
    print user.get(), pw.get()
    try:
        db = MySQLdb(config.server_link, user.get(), pw.get(), config.database)
        tkmb.showinfo("Success!","Database login successful.\n\
        Click Browse to load TLA spreadsheet.")
        tk.Button(root, text = "Browse", command = openFile, width = 10).pack()
        return True
    except:
        tkmb.showerror("Error", "Login failed. Try again.")
        return False

#GUI setup
root = tk.Tk()
root.title("TLA Database Tool")

user_label = tk.Label(root, text = "username").pack()
user = tk.Entry(root, textvariable = tk.StringVar()).pack()
pw_label = tk.Label(root, text = "password").pack()
pw = tk.Entry(root, show = "*", textvariable = tk.StringVar()).pack()
login_button = tk.Button(root, text = "Login", command = lambda: logintoDB(user,pw)).pack()
root.mainloop()

1 Answer 1

1

The following lines are wrong in your code:

user = tk.Entry(root, textvariable = tk.StringVar()).pack()
pw = tk.Entry(root, show = "*", textvariable = tk.StringVar()).pack()

clearly the variables user and pw above point to the Entry widget objects, not to the textvariable associated with those objects.

Rather you should set a new variable using the textvariable attribute and pass it as a parameter using your lambda operator.

Here's a simple example to fetch text from Text widget.

from Tkinter import *
root = Tk()
svalue = StringVar() # defines the widget state as string
w = Entry(root,textvariable=svalue) # adds a textarea widget
w.pack()
def act():
    print "you entered"
    print '%s' % svalue.get()
foo = Button(root,text="Press Me", command=act)
foo.pack()
root.mainloop()

Notice how I set a separate variable svalue and passed it to to the textvariable attribute of the Entry widget.

In reply to your comment

In fact now that I closely look at your widget creation, you are creating the widget and packing it in the same line and then keeping a reference to it like:

usr = Entry().pack()

Since pack() returns null, you are left with a null value for usr.

Instead do this:

usr = Entry(root,textvariable=svalue) # create here
usr.pack() # now pack

Now usr will have a reference to the Entry widget.

In fact I got your entire program to work simply by changing the lines to:

user = tk.Entry(root, textvariable = tk.StringVar())
user.pack()
pw_label = tk.Label(root, text = "password").pack()
pw = tk.Entry(root, show = "*", textvariable = tk.StringVar())
pw.pack()
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks that works but I'm confused as to why I can't call some_Entry_obj.get(). I have seen examples where the Entry object has a get method that can be called and returns the string stored.
modified answer above to answer your question
Ah what a silly error! That makes so much sense. Thanks!
You might also want to mention that you don't need a textvariable since you're only ever using it to get the value. You can get the value directly from the widget and have one less object to manage.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.