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()
The code doesn’t work because
StringVarandIntVarare not the typical Python objectsstrandint, 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)tosavedata(text1.get(), int1.get())so you actually obtain the values stored in them. Secondly, the way you define the value for thecommandparameter in theButtonwidget 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 tocommand = lambda: savedata(...). Thirdly, you are callingbut that will certainly fail, because you are passing a tuple to
execute, what you actually want is:Now your code works, but there is no need to use Tcl variables here.