Hi, I've been using tkinter to write a program that has a root window and many toplevel windows. I was able to create them successfully but my next step was to incorporate mysql with it so it would actually store any data that was entered in the various entry fields. I started with a typical script to connect to mysql with the username and password hardcoded and was able to have data saved into the database. My problem now is that I want a login window where a user will enter their own username and password and if correct, it will connect to mysql. From there, toplevel windows can be opened and data from entry fields stored. The code below is a mock up of what I have (up over 1300 lines now) and it will do the login with valid username/pass but now the other sql commands won't execute because I guess the 'global name cursor' isn't defined, or is out of the loop? How can I correct this?

from Tkinter import *
import sys
import MySQLdb

 

# Toplevel window that opens when "NEXT" button is clicked in "NextWindow" widget
def NewWindow():
    win = Toplevel()

    # entry boxes put in a frame, text stored in variables k, l
    ent_frame = Frame(win)
    Label(ent_frame, text="ITEM:").pack(side=LEFT)
    k = Entry(ent_frame, width=15)
    k.pack(side=LEFT)
    Label(ent_frame, text="BRAND:").pack(side=LEFT)
    l = Entry(ent_frame, width=15)
    l.pack(side=LEFT)
    ent_frame.pack()

    # using get method for entry boxes above
    def SaveIt():
        m = k.get()
        n = l.get()
        # executing a sql command and inserting m,n
        cursor.execute ("""INSERT INTO info (item, brand) VALUES("%s", "%s")"""% (m,n))
        print "Number of rows inserted: %d" % cursor.rowcount
        conn.close()
       
    Button(win, text="Save",command=SaveIt).pack(side=BOTTOM)
    Button(win, text="Next", command=win.destroy).pack(side=BOTTOM)


# Toplevel window that opens when "Next" is clicked from root window.
def NextWindow():
    win = Toplevel()

    # entry boxes put in a frame, text stored in variables c,d
    ent_frame = Frame(win)
    Label(ent_frame, text="CITY:").pack(side=LEFT)
    c = Entry(ent_frame, width=15)
    c.pack(side=LEFT)
    Label(ent_frame, text="STATE:").pack(side=LEFT)
    d = Entry(ent_frame, width=15)
    d.pack(side=LEFT)
    ent_frame.pack()

    # using get method for entry boxes
    def SaveThis():
        h = c.get()
        j = d.get()
        # executing a sql command and inserting h,j
        cursor.execute ("""INSERT INTO info (city, state) VALUES("%s", "%s")"""% (h,j))
        print "Number of rows inserted: %d" % cursor.rowcount
        conn.close()
         
    # Click 'save' run 'SaveThis' and executes sql command. 'Next' opens toplevel
    Button(win, text="Save",command=SaveThis).pack(side=BOTTOM)
    Button(win, text="Next", command=NewWindow).pack(side=BOTTOM)
    


# Takes text entered in root window of user & pass and enters them in sql connect
def SaveData():
    f = a.get()
    g = b.get()
    try:
      conn = MySQLdb.connect (host = "localhost",
                              user = "%s" % (f),
                              passwd = "%s" % (g),
                              db = "maindb") 
    # error if wrong username or password 
    except MySQLdb.Error, e:
      print "Error %d: %s" % (e.args[0], e.args[1])
      sys.exit (1)

      cursor = conn.cursor () 
     
root = Tk()
 
# frame containing 2 entries which will be stored in variables a,b
ent_frame = Frame(root)
Label(ent_frame, text="USERNAME:").pack(side=LEFT)
a = Entry(ent_frame, width=15)
a.pack(side=LEFT)
Label(ent_frame, text="PASSWORD:").pack(side=LEFT)
b = Entry(ent_frame, width=15)
b.pack(side=LEFT)
ent_frame.pack()
 
# Clicking 'login' runs 'SaveData' and passes info into sql and connects with
# username and password.
Button(root, text="Login",command=SaveData).pack(side=BOTTOM)
# opens a toplevel window with more entry fields
Button(root, text="Next", command=NextWindow).pack(side=BOTTOM)
 
mainloop()

When I do it this way it works:

from Tkinter import *
import sys
import MySQLdb

conn = MySQLdb.connect (host = "localhost",
                           user = "kiddo39",
                           passwd = "somepass",
                           db = "maindb")
cursor = conn.cursor () 
..........code................

value of cursor is local, it can not work. Declare it global in beginning of the function or call save_this(cursor) from the function or put the code of save_this in end of SaveData. Change the functions name to save_data to follow Python naming convention.

Edited 6 Years Ago by pyTony: n/a

I've been trying those suggestions but still can't get it to work. Is this what you meant by putting SaveThis at the end of SaveData and changing it's name? Can you give me some examples of declaring it globally?

def SaveData():
    f = a.get()
    g = b.get()
    ...code...

    def save_data(cursor):
        h = c.get()
        j = d.get
        ...code...

Edited 6 Years Ago by kiddo39: forgot ending 'code' bracket

Global vars:

def set_x(parameter):
    global x # this is necessary to change the global value inside function
    # global is actually not global, but module level variable
    x = parameter

x=3
print x
set_x(9)
print x

This is usually not the recommended way. If you are using objects, you should use object attributes, otherwise it is better to pass mutable parameter to function.

Edited 6 Years Ago by pyTony: n/a

This article has been dead for over six months. Start a new discussion instead.