Reputation: 563
I am coding a small program to simply save text data and integer data
into an SQLite3
database.
I have created the db called test.db
with the following code:
con = sqlite3.connect('test.db')
cur = con.cursor()
cur.execute('drop table if exists data')
cur.execute('create table data(t1 TEXT, i1 INT)')
con.commit()
print('DB created')
The problem is when I run it it tells
me that the cur.execute
line requires strings as parameters, but I have already defined text1
as string with StringVar
.
from tkinter import *
from tkinter import ttk
import sqlite3
def savedata(text1, int1):
con = sqlite3.connect('test.db')
cur = con.cursor()
cur.execute(('INSERT INTO data (t1, i1) VALUES (?,?)', (text1, int1)))
con.commit()
print('record inserted in data')
root = Tk()
root.title("Little Program To Save Data")
mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column = 0, row = 0, sticky = (N,W,E,S))
mainframe.columnconfigure(0, weight = 1)
mainframe.rowconfigure(0, weight = 1)
text1 = StringVar()
text_entry = ttk.Entry(mainframe, width = 20, textvariable=text1)
text_entry.grid(column = 2, row = 1, sticky = (N,W,E,S))
int1 = IntVar()
int_entry = ttk.Entry(mainframe, width = 20, textvariable=int1)
int_entry.grid(column = 2, row = 2, sticky = (N,W,E,S))
ttk.Button(mainframe, text = "Save!", command=savedata(text1, int1)).grid(column = 3, row = 3, sticky = (W, E))
for child in mainframe.winfo_children():
child.grid_configure(padx = 5, pady = 5)
root.mainloop()
Upvotes: 1
Views: 4696
Reputation: 19221
The code doesn't work because StringVar
and IntVar
are not the typical Python objects str
and int
, they actually represent Tcl variables which you might happen to set to contain values that can be classified either as string or integer.
The first thing you need to do is change savedata(text1, int1)
to savedata(text1.get(), int1.get())
so you actually obtain the values stored in them. Secondly, the way you define the value for the command
parameter in the Button
widget is wrong because you are executing it instead of passing a function to be executed when you actually click the button. That is fixed by changing that part to command = lambda: savedata(...)
. Thirdly, you are calling
cur.execute(('INSERT INTO data (t1, i1) VALUES (?,?)', (text1, int1)))
but that will certainly fail, because you are passing a tuple to execute
, what you actually want is:
cur.execute('INSERT INTO data (t1, i1) VALUES (?,?)', (text1, int1))
Now your code works, but there is no need to use Tcl variables here.
Upvotes: 2