JoeW373 JoeW373 - 1 month ago 12
Python Question

How to append to sqlite database when the function uses variables stored in another function

In my program I am using tkinter as a gui and I have entries of where the user can enter an ID for a book and the name of a book to add the book to the database records (using an sqlite db)

def bookListEntry(event):
top = Toplevel()
top.title("Append to book list")
bookIDLabel = Label(top, text= "bookID: ").grid(row = 0)
bookIDEntry = Entry(top).grid(row = 0, column = 1)
bookNamelabel = Label(top, text = "bookName: ").grid(row = 1)
bookNameEntry = Entry(top).grid(row = 1, column = 1)
quitButton = Button(top, text = "Exit", command = top.destroy)
quitButton.grid(row = 2, column = 1)
appendButton = Button(top, text = "Append", command = appendToBookList)
appendButton.grid(row = 2, column = 2)


def appendToBookList():
c.execute("INSERT INTO bookList VALUES (?, ?);",(bookIDEntry, bookNameEntry))
conn.commit()


However, I am getting the error "NameError: name 'bookIDEntry' is not defined"
I have knowledge on global and local variables and I'm prety sure it's not working as it's a local variable but I can't think of a way for appendToBookList() of knowing the values of the entries.
Also, another problem is that I think if it worked then it may append the name of the variables in the fields in the db, rather than what is typed into the entry boxes. Any idea of how I could solve these problems? Thank you

Answer

Not tested

def book_list_entry(event):
    top = Toplevel()
    top.title("Append to book list")

    Label(top, text="bookID: ").grid(row=0)

    book_id_entry = Entry(top)
    book_id_entry.grid(row=0, column=1)

    Label(top, text="bookName: ").grid(row=1)

    book_name_entry = Entry(top)
    book_name_entry.grid(row=1, column=1)

    b = Button(top, text="Exit", command=top.destroy)
    b.grid(row=2, column=1)

    b = Button(top, text="Append", command=lambda:append_to_bookList(book_id_entry.get(), book_name_entry.get())
    b.grid(row=2, column=2)


def append_to_bookList(book_id, book_name):
    c.execute("INSERT INTO bookList VALUES (?, ?);", (book_id, book_name))
    conn.commit()

If you need variable var then you have to use

var = Widget(...)
var.grid(...)

You can't do

var = Widget(...).grid(...)

because grid/pack/place returns None and you will get None in var instead of expected widget.

If you don't need var than you can do

Widget(...).grid(...)

You have to use entry.get() to get text from entry

book_id_entry.get(), book_name_entry.get()

You can call append_to_BookList with arguments (text from entries) but you have to use lambda to create anonymouse function without variables.

command=lambda:append_to_bookList(book_id_entry.get(), book_name_entry.get())

It is similar to

temp_function_name = lambda:append_to_bookList(book_id_entry.get(), book_name_entry.get())

Button( ..., command=temp_function_name)

I use prefered

  • lower_case_names for functions and varaibles.
  • inside brackets = without spaces.