Search code examples
pythonpython-3.xsqlitetkintertkinter-entry

How to insert values from my database to my entries? Tkinter


I don't know what I'm doing wrong when I'm trying to insert some values from my database to my entries. I have a main interface with the same code working well, but I've created a secondary window and tried to make work almost the same code but it's not working. It gives me this error:

sqlite3.OperationalError: incomplete input

This is my code:

myid = StringVar()
myname = StringVar()
myowner = StringVar()
mycel = StringVar()

id_entry = Entry(windows2, textvariable=myid)
name_entry = Entry(windows2, textvariable=myname)
owner_id = Entry(windows2, textvariable=myowner)
cel_id = Entry(windows2, textvariable=mycel)

btn_search = Button(windows2, text='SEARCH', command=lambda: search())
btn_search.place(x=930, y=12, width='60', height='26')

def search():

    conn = sqlite3.connect('db1.db')
    c = conn.cursor()
    c.execute("SELECT * FROM regis WHERE idcard=" + myid.get())

    theuser = c.fetchall()

    for user in theuser:
        myid.set(user[0])
        myname.set(user[1])
        myowner.set(user[8])
        mycel.set(user[9])

    conn.commit()

    if theuser:
       messagebox.showinfo(title='ID Found', message='User found')

    else:
       messagebox.showerror(tittle=None, message='Wrong ID')


Solution

  • Explanation:

    What you should be doing is adding a master argument to ALL tkinter widgets. When we create Tk(), it creates a tcl interpreter. Each tcl interpreter has its own memory for its widgets. So when you say StringVar(), it doesn't know which tcl interpreter to belong to, so it implicitly uses the first created Tk(). But the first created Tk() might not hold the widget you are associating your StringVar to(with textvariable), so it will not have its value stored.

    Solution:

    What you can do is, either explicitly mention which instance of Tk() to belong to, or use Toplevel() for the creation of child windows(like mention by acw1668).

    StringVar(master=newwindow) # Same with other tkinter variables and all widgets too
    

    or

    newwindow = Toplevel() # Recommended because tkinter was made to work like this?
    

    Also make sure to sanitize your inputs so it wont be prone to SQL injections:

    c.execute("SELECT * FROM regis WHERE idcard=?",(myid.get(),))
    

    Though I would never use StringVar for entry widgets as long as I have to use trace on them. They have their own get() method which works the same way.