Saving entries on tkinter to sqlite3 - python

thanks in advance for any help!
Ive been looking online for a solution and have struggled to find one. Im trying to save some data from a entry text box on tkinter to a table in SQLite3 but am getting the same error every time no matter what I try. Code below.
please note, I only started to learn coding from youtube videos a few days ago. apologies if this is really simple!
**python file code**
from tkinter import *
import sqlite3
import tkinter.messagebox
# connect to database
conn = sqlite3.connect("RMS.db")
c = conn.cursor()
# tkinter window
class Application:
def __init__(self, master):
self.master = master
# Creating frames in the master
self.left = Frame(master, width=200, height=60, bg="grey")
self.left.pack(side=LEFT)
self.right = Frame(master, width=0, height=0, bg="grey")
self.right.pack(side=RIGHT)
# labels for window
self.driverlevel = Label(self.left, text="Driver Level:", font="calabri 12 bold", fg="white", bg="grey")
self.driverlevel.place(x=1, y=2)
# Entries for left window
self.driverlevel_ent = Entry(self.left, width=20)
self.driverlevel_ent.place(x=5, y=27)
# Save Button
self.submit = Button(self.left, text="Add", font="calabri 12 bold", fg="white", bg="grey", command=self.addlevel)
self.submit.place(x=140, y=15)
def addlevel(self):
self.val1 = self.driverlevel_ent.get()
if self.val1 == "":
tkinter.messagebox.showinfo("Warning", "Please Enter a Value")
else:
sql = "INSERT INTO 'driverlevel' (Level,) VALUES(?,)"
c.execute(sql, (self.val1))
conn.commit()
tkinter.messagebox.showinfo("Success", "Driver Level Added")
# objects
root = Tk()
b = Application(root)
root.geometry("200x60+0+0")
root.resizable(False, False)
root.title("Add Driver Level")
root.mainloop()
**error message when saving**
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\*****\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
File "C:/Users/*****/PycharmProjects/******/driverlevel.py", line 41, in addlevel
c.execute(sql, (self.val1))
sqlite3.OperationalError: near ")": syntax error
no idea how to overcome this..
Thanks, Josh

You inserted , after Level, and ?, which was suppose to be this "INSERT INTO 'driverlevel' (Level) VALUES(?) then insert the comma , at the end of (self.val1,) to see it as a tuple because you can insert data into sqlite3 as tuple
You can also insert the data this way
sql = "INSERT INTO driverlevel (Level) VALUES(?,)"
conn = sqlite3.connect("RMS.db")
c = conn.cursor()
c.execute("INSERT INTO driverlevel(level)VALUES(?)", (self.val1,))
conn.commit()
tkinter.messagebox.showinfo("Success", "Driver Level Added")
Make sure you closed the db after insertion.
Full code
from tkinter import *
import sqlite3
import tkinter.messagebox
# connect to database
conn = sqlite3.connect("RMS.db")
c = conn.cursor()
c.execute("CREATE TABLE IF NOT EXISTS driverlevel(level text, age text)")
conn.commit()
conn.close()
# tkinter window
class Application:
def __init__(self, master):
self.master = master
# Creating frames in the master
self.left = Frame(master, width=200, height=60, bg="grey")
self.left.pack(side=LEFT)
self.right = Frame(master, width=0, height=0, bg="grey")
self.right.pack(side=RIGHT)
# labels for window
self.driverlevel = Label(self.left, text="Driver Level:", font="calabri 12 bold", fg="white", bg="grey")
self.driverlevel.place(x=1, y=2)
# Entries for left window
self.driverlevel_ent = Entry(self.left, width=20)
self.driverlevel_ent.place(x=5, y=27)
# Save Button
self.submit = Button(self.left, text="Add", font="calabri 12 bold", fg="white", bg="grey", command=self.addlevel)
self.submit.place(x=140, y=15)
def addlevel(self):
self.val1 = self.driverlevel_ent.get()
if self.val1 == "":
tkinter.messagebox.showinfo("Warning", "Please Enter a Value")
else:
#sql = "INSERT INTO driverlevel (Level) VALUES(?,)"
# conn = sqlite3.connect("RMS.db")
# c = conn.cursor()
# c.execute("INSERT INTO driverlevel(level)VALUES(?)", (self.val1,))
# conn.commit()
# tkinter.messagebox.showinfo("Success", "Driver Level Added")
conn = sqlite3.connect("RMS.db")
c = conn.cursor()
sql = "INSERT INTO 'driverlevel' (Level) VALUES(?)"
c.execute(sql, (self.val1,))
conn.commit()
conn.close()
tkinter.messagebox.showinfo("Success", "Driver Level Added")
# objects
root = Tk()
b = Application(root)
root.geometry("200x60+0+0")
root.resizable(False, False)
root.title("Add Driver Level")
root.mainloop()

Related

Python / Tkinter - Error message when I try to save changes

I am building a database for tools and matrials list in Python using Tkinter for the GUI. I am running into issues when I try to edit data. Everything works until I click the save button in the editor window. It says: sqlite3.ProgrammingError: You did not supply a value for binding 1. Can anyone see what I am doing wrong here?
Here is my code:
from tkinter import *
import sqlite3
mud = Tk()
mud.title("Mud Data")
mud.geometry("400x600")
# Create database
conn = sqlite3.connect('well_sav.db')
# Create cursor
c = conn.cursor()
# Create table
# c.execute("""CREATE TABLE mud (
# mud_type text,
# mud_weight real ,
# mud_viscosity real,
# mud_pit_number real
# )""")
# Create Submit Function for DB
def submit():
# Connect to DB
conn = sqlite3.connect('well_sav.db')
# Create cursor
c = conn.cursor()
# Insert into table
c.execute("INSERT INTO mud VALUES (:mud_type, :mud_weight, :mud_viscosity, :mud_pit_number)",
{
'mud_type': mud_type.get(),
'mud_weight': mud_weight.get(),
'mud_viscosity': mud_viscosity.get(),
'mud_pit_number': mud_pit_number.get()
})
# Commit changes
conn.commit()
# Close connection
conn.close()
# Clear The Text Boxes
mud_type.delete(0, END)
mud_weight.delete(0, END)
mud_viscosity.delete(0, END)
mud_pit_number.delete(0, END)
# Function to edit a record
def edit():
# Create global variables
global editor
global mud_type_editor
global mud_weight_editor
global mud_viscosity_editor
global mud_pit_number_editor
editor = Tk()
editor.title("Edit mud")
editor.geometry("400x200")
conn = sqlite3.connect('well_sav.db')
c = conn.cursor()
record_id = delete_box.get()
c.execute("SELECT * FROM mud WHERE oid = " + record_id)
records = c.fetchall()
mud_type_editor = Entry(editor, width=30)
mud_type_editor.grid(row=0, column=1, pady=(10, 0))
mud_weight_editor = Entry(editor, width=30)
mud_weight_editor.grid(row=1, column=1)
mud_viscosity_editor = Entry(editor, width=30)
mud_viscosity_editor.grid(row=2, column=1)
mud_pit_number_editor = Entry(editor, width=30)
mud_pit_number_editor.grid(row=3, column=1)
# Create Text box Label
mud_type_label = Label(editor, text="Mud Type")
mud_type_label.grid(row=0, column=0, pady=(10, 0))
mud_weight_label = Label(editor, text="Mud Weight")
mud_weight_label.grid(row=1, column=0)
mud_viscosity_label = Label(editor, text="Mud Viscosity")
mud_viscosity_label.grid(row=2, column=0)
mud_pit_number_label = Label(editor, text="Mud Pit Number")
mud_pit_number_label.grid(row=3, column=0)
# Loop through results
for record in records:
mud_type_editor.insert(0, record[0])
mud_weight_editor.insert(0, record[1])
mud_viscosity_editor.insert(0, record[2])
mud_pit_number_editor.insert(0, record[3])
# Create save button
edit_button = Button(editor, text="Save Update", command=update)
edit_button.grid(row=7, column=1, pady=5, padx=5, ipadx=98)
conn.commit()
conn.close()
# Fucntion for updates
def update():
conn = sqlite3.connect('well_sav.db')
c = conn.cursor()
record_id = delete_box.get()
c.execute("""UPDATE mud SET
mud_type = :name,
mud_weight = :length,
mud_viscosity = :inside_diameter,
mud_pit_number = :outside_diameter
WHERE oid = :oid""",
{
'mud_type': mud_type_editor.get(),
'mud_weight': mud_weight_editor.get(),
'mud_viscosity': mud_viscosity_editor.get(),
'mud_pit_number': mud_pit_number_editor.get(),
'oid': record_id
})
conn.commit()
conn.close()
editor.destroy()
# Function to delete a record
def delete():
conn = sqlite3.connect('well_sav.db')
c = conn.cursor()
c.execute("DELETE FROM mud WHERE oid = " + delete_box.get())
conn.commit()
conn.close()
# Create Query Function
def query():
# Connect to DB
conn = sqlite3.connect('well_sav.db')
# Create cursor
c = conn.cursor()
# Query the DB
c.execute("SELECT *, oid FROM mud")
records = c.fetchall()
# print(records)
# Loop through results
print_records = ''
for record in records:
print_records += str(record[0]) + "\t " + str(record[1]) + \
"\t " + str(record[2]) + "\t " + \
str(record[3]) + str(record[4]) + "\n"
query_label = Label(mud, text=print_records)
query_label.grid(row=20, column=0, columnspan=2)
# Commit changes
conn.commit()
# Close connection
conn.close()
# Math Functions
def volume_per_foot(bha_result_text):
bha_gallons_per_foot = float(mud_viscosity.get()) * \
float(mud_viscosity.get()) / 1029.4
bha_result_text.set(str(bha_gallons_per_foot))
# Create Text Boxes
mud_type = Entry(mud, width=30)
mud_type.grid(row=0, column=1, pady=(10, 0))
mud_weight = Entry(mud, width=30)
mud_weight.grid(row=1, column=1)
mud_viscosity = Entry(mud, width=30)
mud_viscosity.grid(row=2, column=1)
mud_pit_number = Entry(mud, width=30)
mud_pit_number.grid(row=3, column=1)
delete_box = Entry(mud, width=30)
delete_box.grid(row=6, column=1)
# Create Text box Label
mud_type_label = Label(mud, text="Mud Type")
mud_type_label.grid(row=0, column=0, pady=(10, 0))
mud_weight_label = Label(mud, text="Mud Weight")
mud_weight_label.grid(row=1, column=0)
mud_viscosity_label = Label(mud, text="Mud Viscosity")
mud_viscosity_label.grid(row=2, column=0)
mud_pit_number_label = Label(mud, text="Pit Number")
mud_pit_number_label.grid(row=3, column=0)
delete_box_label = Label(mud, text="Select ID")
delete_box_label.grid(row=6, column=0)
# Create Submit Button
submit_button = Button(mud, text="Save", command=submit)
submit_button.grid(row=4, column=1, pady=5, padx=5, ipadx=121)
# Create Query Button
query_button = Button(mud, text="Show Muds", command=query)
query_button.grid(row=5, column=1, pady=5, padx=5, ipadx=79)
# Create edit button
edit_button = Button(mud, text="Edit Muds", command=edit)
edit_button.grid(row=7, column=1, pady=5, padx=5, ipadx=87)
# Create delete button
delete_button = Button(mud, text="Delete Mud", command=delete)
delete_button.grid(row=8, column=1, pady=5, padx=5, ipadx=80)
# Commit changes
conn.commit()
# Close connection
conn.close()
mud.mainloop()
And here is the error message:
Exception in Tkinter callback
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/tkinter/__init__.py", line 1883, in __call__
return self.func(*args)
File "mud.py", line 123, in update
c.execute("""UPDATE mud SET
sqlite3.ProgrammingError: You did not supply a value for binding 1.
Hi #LoudEye and welcome to Stack Overflow! Try using ? instead of : like this:
c.execute("UPDATE mud SET mud_type=?,mud_weight = ?, mud_viscosity=?, mud_pit_number = ? WHERE...",(mud_type_editor.get(), mud_weight_editor.get(),mud_viscosity_editor.get(),mud_pit_number_editor.get()))
Note: You should also use WHERE also with question mark like I've used with SET

Python tkinter listbox bind on <Button-1> only works on second click

I apologize upfront if there is another discussion that already addresses this issue, but I could not find anything. I am new to Python (and for that matter programming other than a little bit of Pascal back in the 90's).
I am building a GUI with tk Entry boxes for a user to enter values, which is then stored in a sqlite db. I would like the user to be able to click on the values from one of the fields in a listbox, which would then re-populate the tk Entry boxes with the values for all fields for the selected record. I have been able to make this work, but it only works on the second click as I bind the list box to the function to populate the tk Entry boxes on Button-1. The first click generates the following error, which I have seen references to in other questions, but I cannot translate those answers to my situation:
Error:
Traceback (most recent call last):
File "...\Python\Python38-32\lib\tkinter__init__.py", line 1883, in call
return self.func(*args)
File "fe.py", line 108, in selectitem
selecteditem.append(lb1.get(ndex))
File "...\Python\Python38-32\lib\tkinter__init__.py", line 3182, in get
return self.tk.call(self._w, 'get', first)
_tkinter.TclError: bad listbox index "": must be active, anchor, end, #x,y, or a number
Here is example code that replicates the error - to use, first add a a couple of values through the Setup -> Items menu by filling in the VAL and REF boxes and clicking the Add Item button. Then click on one of the items in the list box. The first click should generate the error above. When you click a second time the Entry boxes should populate:
```
import sqlite3
import itertools
import tkinter as tk
from tkinter import ttk
INTRO_FONT = ("Arial", 72)
LARGE_FONT = ("Arial", 12)
NORMAL_FONT = ("Arial", 10)
SMALL_FONT = ("Arial", 8)
#Function to create database
def create_db():
conn = sqlite3.connect("demo.db")
cur = conn.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS demotable (id INTEGER PRIMARY KEY, val TEXT, ref TEXT)")
conn.commit()
conn.close()
#Create database
create_db()
#Main Class to manage frames
class demo(tk.Tk):
def __init__(self,*args,**kwargs):
tk.Tk.__init__(self,*args,**kwargs)
container = tk.Frame(self)
container.pack(side="top",fill="both",expand=True)
container.grid_rowconfigure(0,weight=1)
container.grid_columnconfigure(0,weight=1)
menubar = tk.Menu(container)
filemenu = tk.Menu(menubar,tearoff=0)
filemenu.add_command(label="Exit", command=quit)
menubar.add_cascade(label="File", menu=filemenu)
setupmenu = tk.Menu(menubar, tearoff=0)
setupmenu.add_command(label="Items",command = lambda: self.show_frame(Itemsetuppage))
menubar.add_cascade(label="Setup", menu=setupmenu)
tk.Tk.config(self, menu=menubar)
self.frames={}
for F in (Itemsetuppage,Itemsetuppage):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(Itemsetuppage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
# Frame that inserts and loads values
class Itemsetuppage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
#Function to populate listbox with values
def popitemlist(self):
lb1.delete(0, tk.END)
for item in itemlist():
lb1.insert(tk.END, item)
#Function to add new item to database
def additem():
additem_db(val.get(), ref.get())
val_entry.delete(0, 'end')
ref_entry.delete(0, 'end')
popitemlist(self)
#Function used to populate tk.Entry boxes from database when item in listbox is clicked
def selectitem(event):
global selecteditem
selecteditem = []
ndex = lb1.curselection()
selecteditem.append(lb1.get(ndex))
itemquery = select_item(selecteditem)
val_entry.delete(0, 'end')
val_entry.insert(0, itemquery[1])
ref_entry.delete(0, 'end')
ref_entry.insert(0, itemquery[2])
#Function to query database for values to populate lb1
def itemlist():
conn = sqlite3.connect("demo.db")
cur = conn.cursor()
cur.execute("SELECT DISTINCT val FROM demotable")
results = cur.fetchall()
itemlist = list(itertools.chain(*results))
conn.commit()
conn.close()
return itemlist
#Function to insert values from tk.Entry boxes to database
def additem_db(val, ref):
conn = sqlite3.connect("demo.db")
cur = conn.cursor()
cur.execute("INSERT OR IGNORE INTO demotable VALUES (NULL, ?, ?)",(val,ref))
conn.commit()
conn.close()
#Function to query database for individual record to populate tk.Entry boxes when item is clicked in lb1
def select_item(val):
conn = sqlite3.connect("demo.db")
cur = conn.cursor()
cur.execute("SELECT * FROM demotable WHERE val=?",(val))
results = cur.fetchall()
itemdetail = list(itertools.chain(*results))
conn.commit()
conn.close()
return itemdetail
l1 = tk.Label(self, text="Values in database:")
l1.grid(row=0, column=0, padx=5, pady=5)
lb1 = tk.Listbox(self, selectmode=tk.SINGLE)
lb1.grid(row=1, column=0, padx=5, pady=5)
popitemlist(self)
lb1.bind("<Button-1>", selectitem)
l2 = tk.Label(self, text="Type val into entry box to store:")
l2.grid(row=0, column=1, padx=5, pady=5)
val = tk.StringVar(self)
val_entry = tk.Entry(self, textvariable=val)
val_entry.grid(row=0, column=2, padx=5, pady=5)
l2 = tk.Label(self, text="Type ref into entry box to store:")
l2.grid(row=1, column=1, padx=5, pady=5)
ref = tk.StringVar(self)
ref_entry = tk.Entry(self, textvariable=ref)
ref_entry.grid(row=1, column=2, padx=5, pady=5)
b1 = tk.Button(self, text="Add item",command=additem)
b1.grid(row=2, column=2, padx=5, pady=5)
app = demo()
app.geometry("480x240")
app.mainloop()
```
Thank you & apologies if my code offends anyone!
Not having run your code as I have no sqlite3 database I may be way off, but listbox generates a virtual event when a value is selected <<ListboxSelect>> which you can bind to. Try replacing:
lb1.bind("<Button-1>", selectitem)
with
lb1.bind("<<ListboxSelect>>", selectitem)
Also, I think lb1.curselection() returns a tuple..., try printing it and see what you get. In the code I checked I always do lb1.curselection()[0].

function call from a function to a function within a class fails

I'm trying to setup a program where my tkinter GUI functions are in a class and my database functions are in another class. I have a function external to both classes that fails when I try to call a function within the DB class. Can you help me resolve this error? Should both my GUI and any database be in separate functions or is that a poor design. The attached code is a stripped down version to illustrates my issue. Clicking the "View all" button generates the error.
import sqlite3
from tkinter import *
from tkinter import messagebox
class DB:
def __init__(self):
self.conn = sqlite3.connect("mybooks.db")
self.cur = self.conn.cursor()
self.cur.execute(
"CREATE TABLE IF NOT EXISTS book (id INTEGER PRIMARY KEY, title TEXT, author TEXT, isbn INTEGER)")
self.conn.commit()
def __del__(self):
self.conn.close()
def view(self):
self.cur.execute("SELECT * FROM book")
rows = cur.fetchall()
return rows
def view_command():
# there is a problem with the next line
# when rows=DB.view() error is TypeError: view() missing 1 required positional argument: 'self'
# when rows=DB.view(self) error is NameError: name 'self' is not defined
rows=DB.view(self)
for row in rows:
print(row)
class App_GUI(): # create the main window
def __init__(self, master):
self.master = master
self.master.title("My Books")
self.master.l1 = Label(self.master, text="Title")
self.master.l1.grid(row=0, column=0)
self.master.l2 = Label(self.master, text="Author")
self.master.l2.grid(row=0, column=2)
self.master.l3 = Label(self.master, text="ISBN")
self.master.l3.grid(row=1, column=0)
self.master.title_text = StringVar()
self.master.e1 = Entry(self.master, textvariable=self.master.title_text)
self.master.e1.grid(row=0, column=1)
self.master.author_text = StringVar()
self.master.e2 = Entry(self.master, textvariable=self.master.author_text)
self.master.e2.grid(row=0, column=3)
self.master.isbn_text = StringVar()
self.master.e3 = Entry(self.master, textvariable=self.master.isbn_text)
self.master.e3.grid(row=1, column=1)
self.master.list1 = Listbox(self.master, height=6, width=35)
self.master.list1.grid(row=2, column=0, rowspan=6, columnspan=2)
self.master.sb1 = Scrollbar(self.master)
self.master.sb1.grid(row=2, column=2, rowspan=6)
self.master.list1.configure(yscrollcommand=self.master.sb1.set)
self.master.sb1.configure(command=self.master.list1.yview)
self.master.b1 = Button(self.master, text="View all", width=12, command=view_command)
self.master.b1.grid(row=2, column=3)
self.master.b6 = Button(self.master, text="Close", width=12, command=self.master.destroy)
self.master.b6.grid(row=7, column=3)
return
###############################
# Program Main #
###############################
def main():
db = DB()
root = Tk()
def on_closing():
dd = db
if messagebox.askokcancel("Quit", "Do you want to close the application"): # ask the user if he/she wants to close the application
root.destroy()
del dd
root.protocol("WM_DELETE_WINDOW", on_closing) # catch the user closing the window
app = App_GUI(root) # creation of an instance
root.mainloop() # tkinter mainloop
if __name__ == '__main__':
main()
````
You need to pass db to App_GUI and then on to the function:
def view_command(db):
rows = db.view()
for row in rows:
print(row)
class App_GUI(): # create the main window
def __init__(self, master, db):
# other stuff elided ...
self.master.b1 = Button(self.master, text="View all", width=12, command=lambda : view_command(db))
...
def main():
db = DB()
# other stuff elided
app = App_GUI(root, db)
edit: forgot to remove self.
I figured it out! In addition to your changes, I had to remove 'self' from rows=db.view(). Thanks for your help! Revised code:
import sqlite3
from tkinter import *
from tkinter import messagebox
class DB:
def __init__(self):
self.conn = sqlite3.connect("mybooks.db")
self.cur = self.conn.cursor()
self.cur.execute(
"CREATE TABLE IF NOT EXISTS book (id INTEGER PRIMARY KEY, title TEXT, author TEXT, isbn INTEGER)")
self.conn.commit()
def __del__(self):
self.conn.close()
def view(self):
self.cur.execute("SELECT * FROM book")
rows = self.cur.fetchall()
return rows
def view_command(db):
rows=db.view()
for row in rows:
print(row)
class App_GUI(): # create the main window
def __init__(self, master, db):
self.master = master
self.master.title("My Books")
self.master.l1 = Label(self.master, text="Title")
self.master.l1.grid(row=0, column=0)
self.master.l2 = Label(self.master, text="Author")
self.master.l2.grid(row=0, column=2)
self.master.l3 = Label(self.master, text="ISBN")
self.master.l3.grid(row=1, column=0)
self.master.title_text = StringVar()
self.master.e1 = Entry(self.master, textvariable=self.master.title_text)
self.master.e1.grid(row=0, column=1)
self.master.author_text = StringVar()
self.master.e2 = Entry(self.master, textvariable=self.master.author_text)
self.master.e2.grid(row=0, column=3)
self.master.isbn_text = StringVar()
self.master.e3 = Entry(self.master, textvariable=self.master.isbn_text)
self.master.e3.grid(row=1, column=1)
self.master.list1 = Listbox(self.master, height=6, width=35)
self.master.list1.grid(row=2, column=0, rowspan=6, columnspan=2)
self.master.sb1 = Scrollbar(self.master)
self.master.sb1.grid(row=2, column=2, rowspan=6)
self.master.list1.configure(yscrollcommand=self.master.sb1.set)
self.master.sb1.configure(command=self.master.list1.yview)
self.master.b1 = Button(self.master, text="View all", width=12, command=lambda : view_command(db))
self.master.b1.grid(row=2, column=3)
self.master.b6 = Button(self.master, text="Close", width=12, command=self.master.destroy)
self.master.b6.grid(row=7, column=3)
return
###############################
# Program Main #
###############################
def main():
db = DB()
root = Tk()
def on_closing():
dd = db
if messagebox.askokcancel("Quit", "Do you want to close the application"): # ask the user if he/she wants to close the application
root.destroy()
del dd
root.protocol("WM_DELETE_WINDOW", on_closing) # catch the user closing the window
app = App_GUI(root, db) # creation of an instance
root.mainloop() # tkinter mainloop
if __name__ == '__main__':
main()

Multiple GUI with Tkinter

I am using Python 3.x, and I'm trying to fetch Dataset records and display them in an extra Window. I'm a bloody beginner and currently I don't see my error. I've checked multiple threads but didn't get the solution. Debugging isn't helping me either.
Here's my approach:
import sqlite3
from tkinter import *
class Overview():
def __init__(self,master):
self.master = master
self.master.geometry('170x110+100+200')
self.master.title('Welcome!')
self.button1 = Button(self.master, text="Show dataset", fg='green', command=self.gotoMenu).grid(
row=1, column=1)
def gotoMenu(self):
# This is the Dataset GUI#
root2 = Toplevel(self.master)
myGUI = Menu(root2)
def main():
root = Tk()
overviewGUI = Overview(root)
root.mainloop()
if __name__ == '__main__':
main()
class Menu:
def __init__(self,master):
# This is the Dataset GUI#
self.connection = sqlite3.connect('test.db')
print("Opened database successfully")
self.cur = self.connection.cursor()
self.master = master
self.master.title('Dataset')
self.master.geometry("320x240")
print("GUI created")
self.dateLabel = Label(self.master, text="Date", width=10)
self.dateLabel.grid(row=0, column=0)
self.BMILabel = Label(self.master, text="Name", width=10)
self.BMILabel.grid(row=0, column=1)
self.stateLabel = Label(self.master, text="ID", width=10)
self.stateLabel.grid(row=0, column=2)
self.insertDS('random')
self.showallrecords()
def showallrecords(self):
data = self.readfromdatabase()
for index, dat in enumerate(data):
Label(self.master, text=dat[2]).grid(row=index + 1, column=0)
Label(self.master, text=dat[1]).grid(row=index + 1, column=1)
Label(self.master, text=dat[0]).grid(row=index + 1, column=2)
def readfromdatabase(self):
self.cur.execute("SELECT * FROM LOGGING")
return self.cur.fetchall()
def createTable(self):
try:
self.connection.execute(
"CREATE TABLE LOGGING(ID INTEGER PRIMARY KEY AUTOINCREMENT,NAME TEXT NOT NULL, TIMESTAMP DATE DEFAULT (datetime('now','localtime')));")
print("Table created successfully")
except:
print("Table already exists")
def insertDS(self, name):
self.connection.execute("INSERT INTO LOGGING (NAME) \
VALUES (?);", [name])
self.connection.commit()
print("Records created successfully")
My Application should start with the "Overview" GUI, on button click I want to see all fetched Datasets from "Menu" Class.
However, after clicking the button the next window is empty and has the title "Welcome" which should be "Dataset"
UPDATE:
I am getting no error, BUT my fetched results won't show in the 2nd Window, and the title isn't self.master.title('Dataset') as initialized in class Menu.
I feel like it's just creating some empty Window without even looking in my Menu Class?
Solution:
python className not defined NameError
Somehow(can't explain why) when I moved the ´name´ block down with the def (even though indentions were right) it worked.
You have overloaded Menu, change your class name by an another name.
And don't use import *

Trouble displaying data from a database in TKinter

I'm creating a database in python using sqlite3 and tkinter. This is my first time doing something like this so I've been using examples on the internet to help build it. This has worked for the most part, however now I need to be able to display the data in the database in a table, and the example I've used doesn't seem to work properly for me. I've tried looking up other solutions, but nothing seems to help.
The problem is that when I go to open up the table, it doesn't get created. The program simply opens a new window and leaves it at that. There are no errors, so I don't know exactly what's wrong.
This is the entire code I've created so far:
from tkinter import *
import sqlite3
con = sqlite3.connect('test.db')
cur = con.cursor()
class Welcome():
def __init__(self,master):
self.master = master
self.master.geometry('170x110+100+200')
self.master.title('Welcome!')
self.label1=Label(self.master,text='Test Database Main Menu',fg='red').grid(row=0,column=1)
self.button1=Button(self.master,text="Enter Data",fg='green',command=self.gotodataentry).grid(row=1,column=1)
self.button2=Button(self.master,text="Data Records",fg='blue',command=self.gotorecords).grid(row=2,column=1)
self.button3=Button(self.master,text="Exit",fg='red',command=self.exit).grid(row=3,column=1)
def exit(self):
self.master.destroy()
def gotodataentry(self):
root2=Toplevel(self.master)
myGUI=DataEntry(root2)
def gotorecords(self):
root2=Toplevel(self.master)
mygui=Records(root2)
class DataEntry():
def __init__(self,master):
self.master = master
self.master.geometry('250x200+100+200')
self.master.title('Data Entry')
self.label2=Label(self.master,text='Welcome to the data entry menu',fg='red').grid(row=0,column=0)
self.label3=Label(self.master,text='Please enter some text',fg='black').grid(row=3,column=0)
self.label4=Label(self.master,text='Please enter a number',fg='black').grid(row=4,column=0)
self.text1=StringVar()
self.text_entry=Entry(self.master,textvariable=self.text1).grid(row=3,column=1)
self.int1=IntVar()
self.int_entry=Entry(self.master,textvariable=self.int1).grid(row=4,column=1)
self.button4=Button(self.master,text="Save",fg='red',command=lambda: self.savedata(self.text1.get(), self.int1.get())).grid(row=7,column=0)
self.button5=Button(self.master,text="Exit",fg='red',command=self.exit).grid(row=9,column=0)
def exit(self):
self.master.destroy()
def savedata(self, 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')
def Records(self):
def __init__(self, master):
self.master = master
self.master.geometry('250x200+100+200')
self.master.title('Records')
self.connection = sqlite3.connect('test.db')
self.cur = self.connection.cursor()
self.textLabel = Label(self.master, text="Text", width=10)
self.textLabel.grid(row=0, column=0)
self.intLabel = Label(self.master, text="Number", width=10)
self.intLabel.grid(row=0, column=1)
self.showallrecords()
def showallrecords(self):
Data = self.readfromdatabase()
for index, dat in enumerate(Data):
Label(self.master, text=dat[0]).grid(row=index+1, column=0)
Label(self.master, text=dat[1]).grid(row=index+1, column=1)
def readfromdatabase(self):
self.cur.execute("SELECT * FROM Data")
return self.cur.fetchall()
def main():
root=Tk()
myGUIWelcome=Welcome(root)
root.mainloop()
if __name__ == '__main__':
main()
And this is the part I'm struggling with:
def Records(self):
def __init__(self, master):
self.master = master
self.master.geometry('250x200+100+200')
self.master.title('Records')
self.connection = sqlite3.connect('test.db')
self.cur = self.connection.cursor()
self.textLabel = Label(self.master, text="Text", width=10)
self.textLabel.grid(row=0, column=0)
self.intLabel = Label(self.master, text="Number", width=10)
self.intLabel.grid(row=0, column=1)
self.showallrecords()
def showallrecords(self):
Data = self.readfromdatabase()
for index, dat in enumerate(Data):
Label(self.master, text=dat[0]).grid(row=index+1, column=0)
Label(self.master, text=dat[1]).grid(row=index+1, column=1)
def readfromdatabase(self):
self.cur.execute("SELECT * FROM Data")
return self.cur.fetchall()
Could someone please help me figure out what's wrong? Sorry if the solution is incredibly simple, like I said this is my first time doing something like this.
You're right that the solution is incredibly simple :D
Change
def Records(self):
To
class Records:
And the code works perfectly

Categories

Resources