Trouble displaying data from a database in TKinter - python

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

Related

CheckBox TKinter to make data visible, and stared

I'm trying to make a password manager, and I made to display the data from a database table, and now I'm trying to add a checkbox, to make the data invisible, for example pass will be ****.
That's the class that I created, everything is working except the CheckBox
class Table:
def __init__(self, root):
self.var = IntVar()
self.box = Checkbutton(root, text="Make the data visible: ", variable=self.var)
self.box.grid(row=0, column=0, columnspan=4)
value = self.var.get()
if value == 1:
res = "*"
else:
res = ""
for i in range(1, total_rows):
for j in range(total_columns):
self.e = Entry(root, width=10, fg='#2cc77f', font=('Poor Richard', 16), show=res)
self.e.grid(row=i, column=j)
self.e.insert(END, lst[i-1][j])
And this is how I all this class
conn = sqlite3.connect('database.db')
c = conn.cursor()
def openTab():
c.execute('SELECT * FROM vault')
return c.fetchall()
lst = openTab()
total_rows = len(lst)
total_columns = len(lst[0])
root = Tk()
t = Table(root)
root.mainloop()
Can somebody tell me, what am I doing wrong?

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()

Saving entries on tkinter to sqlite3

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()

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 *

How can I add code to the following code to clear the entry field once i have entered the data?

I entered this thinking it might work but it doesn't. Not sure if this is correct or I need to change it. It doesn't work so I am guessing it does need changing.
Import from tkinter:
from tkinter import *
import csv
def delete_entries():
for field in fields:
field.delete(0,END)
class App(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.pack()
self.output()
Output:
def output(self):
Heading=StringVar()
Heading.set("Please enter student name below")
Label(text='Name:').pack(side=LEFT,padx=5,pady=5)
self.n = Entry(root, width=10)
self.n.pack(side=LEFT,padx=5,pady=5)
Text label:
Label(text='Grade:').pack(side=LEFT,padx=5,pady=5)
self.e = Entry(root, width=10)
self.e.pack(side=LEFT,padx=6,pady=6)
self.b = Button(root, text='Submit', command=self.writeToFile)
self.b.pack(side=RIGHT,padx=5,pady=5)
self.b = Button(root, text='Clear', command=self.writeToFile)
self.b.pack(side=RIGHT,padx=5,pady=5)
Write to grade CSV:
def writeToFile(self):
with open('Grades.csv', 'a') as f:
w=csv.writer(f, quoting=csv.QUOTE_ALL)
w.writerow([self.n.get()])
w.writerow([self.e.get()])
if __name__ == "__main__":
root=Tk()
root.title('grade')
root.geometry('380x280')
app=App(master=root)
app.mainloop()
root.mainloop()
Delete_button = Button(root, text = 'Clear', command = delete_entries)
Delete_button.pack()
you can add this to end of the code that submits the entries
self.n.delete(0, END)
self.e.delete(0, END)

Categories

Resources