Am trying to display content entered into entry widget in treeview after saving it in sqlite3 db.The content saved into db but doesn't display the id,Fist name and Surname contents in the treeview.
Your suggestion are welcome to achieve this.
from tkinter import ttk
import tkinter as tk
import sqlite3
def connect():
conn = sqlite3.connect("TRIAL.db")
cur = conn.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS profile(id INTEGER PRIMARY KEY,
First TEXT, Surname TEXT)")
conn.commit()
conn.close()
def Insert():
conn = sqlite3.connect("TRIAL.db")
cur = conn.cursor()
fr=cur.execute("INSERT INTO profile (First, Surname) VALUES(?, ?)",
(first_text.get(), surname_text.get()))
conn.commit()
for items in fr:
tree.insert('', tk.END, values=items)
conn.close()
connect() # this to create the db
root = tk.Tk()
root.geometry("400x400")
tree= ttk.Treeview(root, column=("column", "colunn1"))
tree.heading("#0", text="NUMBER")
tree.heading("#1", text="FIRST NAME")
tree.heading("#2", text="SURNAME")
tree.pack()
first_text = tk.StringVar()
e1 = tk.Entry(root, textvariable=first_text)
e1.pack()
surname_text = tk.StringVar()
e2 = tk.Entry(root, textvariable=surname_text)
e2.pack()
b1 = tk.Button(text="add data", command=Insert)
b1.pack(side=tk.BOTTOM)
root.mainloop()
The problem in your code is that for items in fr does not work. Python sees fr as an empty iterable (put a print statement in the for loop and you will see that it is never executed). So, to insert the data in the treeview, you can get it directly from the entries and retrieve the db id with cur.lastrowid (I have found this solution in the answer to the question How to retrieve inserted id after inserting row in SQLite using Python?):
from tkinter import ttk
import tkinter as tk
import sqlite3
def connect():
conn = sqlite3.connect("TRIAL.db")
cur = conn.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS profile(id INTEGER PRIMARY KEY, First TEXT, Surname TEXT)")
conn.commit()
conn.close()
def Insert():
conn = sqlite3.connect("TRIAL.db")
cur = conn.cursor()
data = (first_text.get(), surname_text.get())
# insert data in db
cur.execute("INSERT INTO profile (First, Surname) VALUES(?, ?)", data)
conn.commit()
# insert data in treeview
tree.insert('', tk.END, text=str(cur.lastrowid), values=data)
conn.close()
connect() # this to create the db
root = tk.Tk()
root.geometry("400x400")
tree= ttk.Treeview(root, column=("column", "colunn1"))
tree.heading("#0", text="NUMBER")
tree.heading("#1", text="FIRST NAME")
tree.heading("#2", text="SURNAME")
tree.pack()
first_text = tk.StringVar()
e1 = tk.Entry(root, textvariable=first_text)
e1.pack()
surname_text = tk.StringVar()
e2 = tk.Entry(root, textvariable=surname_text)
e2.pack()
b1 = tk.Button(text="add data", command=Insert)
b1.pack(side=tk.BOTTOM)
root.mainloop()
EDIT: If you use the columns '#1', '#2', '#3' to avoid using the special
column '#0', then you need to change a bit Insert: you need to pass the row id in values instead of text.
from tkinter import ttk
import tkinter as tk
import sqlite3
def connect():
conn = sqlite3.connect("TRIAL.db")
cur = conn.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS profile(id INTEGER PRIMARY KEY, First TEXT, Surname TEXT)")
conn.commit()
conn.close()
def Insert():
conn = sqlite3.connect("TRIAL.db")
cur = conn.cursor()
data = (first_text.get(), surname_text.get())
# insert data in db
cur.execute("INSERT INTO profile (First, Surname) VALUES(?, ?)", data)
conn.commit()
# insert data in treeview
tree.insert('', tk.END, values=(str(cur.lastrowid),) + data)
conn.close()
connect() # this to create the db
root = tk.Tk()
root.geometry("400x400")
tree = ttk.Treeview(root, column=("column1", "column2", "column3"), show='headings')
tree.heading("#1", text="NUMBER")
tree.heading("#2", text="FIRST NAME")
tree.heading("#3", text="SURNAME")
tree.pack()
first_text = tk.StringVar()
e1 = tk.Entry(root, textvariable=first_text)
e1.pack()
surname_text = tk.StringVar()
e2 = tk.Entry(root, textvariable=surname_text)
e2.pack()
b1 = tk.Button(text="add data", command=Insert)
b1.pack(side=tk.BOTTOM)
root.mainloop()
Related
I'm trying to find a way to create a search bar for a table connected to a DB Browser database. The search bar I'm looking for is the one where you type in the bar, and the program will "hide" any data that does not follow the "requirements" while leaving the ones that do visible. The following code shows what I've tried so far. Hopefully, I made myself clear, and thank you for your help. I don't know how to attach the database so sorry for the inconvenience.
If you remove the code between the '''Triple Apostrophes,''' you should see a table with a button that says SELECT which reveals the data. The Table shown is where I would like the Search bar to control.
Thank you for your help once again.
from tkinter import ttk
import tkinter as tk
from tkinter import *
import sqlite3
ws = Tk()
ws.title('Directory')
ws.geometry('600x400')
ws.attributes('-topmost', True)
ws.attributes('-fullscreen', True)
'''
def Scankey(event):
val = event.widget.get()
print(val)
if val == '':
data = Table1
else:
data = []
for item in Table1:
if val.lower() in item.lower():
data.append(item)
Update(data)
def Update(data):
listbox.delete(0, 'end')
# put new data
for item in data:
listbox.insert('end', item)
ws = Tk()
entry = Entry(was)
entry.pack()
entry.bind('<KeyRelease>', Scankey)
listbox = Listbox(was)
listbox.pack()
Update()
# Connect to the database
def connect():
conn = sqlite3.connect("MEMBERinformation.db")
cur = conn.cursor()
cur.execute(
"CREATE TABLE IF NOT EXISTS ChurchMemberInformation(MemberID TEXT PRIMARY KEY, "
"FirstName TEXT, LastName TEXT)")
conn.commit()
conn.close()
# Populate Treeview table
def View():
conn = sqlite3.connect("MEMBERinformation.db")
cur = conn.cursor()
cur.execute("SELECT FirstName, LastName FROM ChurchMemberInformation")
rows = cur.fetchall()
for row in rows:
print(row) # print all records in the database
tree.insert("", tk.END, values=row)
conn.close()
#Frame
Table1 = Frame(was)
Table1.pack(anchor=CENTER)
# Connect the database
connect()
# Create Treeview widget
tree = ttk.Treeview(Table1, column=("column1", "column2",), show='headings')
tree['columns'] = ('FIRST NAME', 'LAST NAME')
tree.column('FIRST NAME', width=100)
tree.heading("#1", text="FIRST NAME")
tree.column('LAST NAME', width=100)
tree.heading("#2", text="LAST NAME")
tree.pack()
# Create and pack buttons
button1 = tk.Button(text="SELECT", command=View)
button2 = tk.Button(text="QUIT", command=ws.destroy)
button1.pack()
button2.pack()
ws.mainloop()
Hi I am trying to create a db for a golf game I play with my son and am having some issues.
I keep getting the following error when trying to insert data into my db:
pyodbc.ProgrammingError: ('The SQL contains 0 parameter markers, but 1 parameters were supplied', 'HY000')
Here is the code:
import tkinter as TK
from tkinter import *
import pyodbc
golfers=Tk()
golfers.title("Golfers")
golfers.geometry('500x500')
#Databases
#Create a Database or Connect to one
conn = pyodbc.connect('Driver={SQL Server};'
'Server=DESKTOP-SCL1250\SQLEXPRESS01;'
'Database=tgt;'
'Trusted_Connection=yes;')
#Create Cursor
c=conn.cursor()
# c.execute("""CREATE TABLE tours(
# tour_code varchar NOT NULL,
# description varchar (255),
# PRIMARY KEY (tour_code))
# """)
# c.execute("""CREATE TABLE golfers (
# golfer_id int IDENTITY(1,1) NOT NULL,
# last_name varchar (255),
# first_name varchar (255),
# tour_code varchar FOREIGN KEY REFERENCES tours(tour_code)
# PRIMARY KEY (golfer_id))
# """)
def submit():
#Create a Database or Connect to one
conn = pyodbc.connect('Driver={SQL Server};'
'Server=DESKTOP-SCL1250\SQLEXPRESS01;'
'Database=tgt;'
'Trusted_Connection=yes;')
#Create Cursor
c=conn.cursor()
#Insert into table
c.execute('INSERT INTO golfers VALUES(:golfer_id, :last_name, :first_name, :tour_code)',
{
'golfer_id': golfer_id.get(),
'last_name': last_name.get(),
'first_name': first_name.get(),
'tour_code': tour_code.get()
})
#Commit Changes
conn.commit()
#Close Connection
conn.close()
#clear the text boxes
golfer_id.delete(0,END)
last_name.delete(0, END)
first_name.delete(0, END)
tour_code.delete(0,END)
#Create Text Boxes
golfer_id = Entry(golfers, width=30)
golfer_id.grid(row=0, column=1, padx=20)
last_name = Entry(golfers, width=30)
last_name.grid(row=1, column=1, padx=20)
first_name = Entry(golfers, width=30)
first_name.grid(row=2, column=1, padx=20)
tour_code = Entry(golfers, width=30)
tour_code.grid(row=3, column=1, padx=20)
#Create Text Box Labels
golfer_id_label = Label(golfers, text="Golfer ID")
golfer_id_label.grid(row=0, column=0)
last_name_label = Label(golfers, text="Last Name")
last_name_label.grid(row=1, column=0)
first_name_label = Label(golfers, text="First Name")
first_name_label.grid(row=2, column=0)
tour_code_label = Label(golfers, text="Tour Code")
tour_code_label.grid(row=3, column=0)
#Create Submit Button
submit_btn = Button(golfers, text="Add Record", command=submit)
submit_btn.grid(row=6, columnspan=2, pady=10, padx=10, ipadx=100)
#Commit Changes
conn.commit()
#Close Connection
conn.close()
golfers.mainloop()
Any help would be appreciated.
I've a python script that uses tkinter and a button to get data from MySQL but every time I press the button the data gets duplicated like that:
Code below:
from tkinter import ttk
import tkinter as tk
import mysql.connector
def View():
mydb = mysql.connector.connect(
host="localhost",
user="",
password="",
database=""
)
mycursor = mydb.cursor()
mycursor.execute("SELECT * FROM patients")
rows = mycursor.fetchall()
for row in rows:
print(row)
tree.insert("", tk.END, values=row)
mydb.close()
# connect to the database
root = tk.Tk()
root.geometry("900x350")
tree = ttk.Treeview(root, column=("c1", "c2", "c3"), show='headings')
tree.column("#1", anchor=tk.CENTER)
tree.heading("#1", text="ID")
tree.column("#2", anchor=tk.CENTER)
tree.heading("#2", text="First Name")
tree.column("#3", anchor=tk.CENTER)
tree.heading("#3", text="Country")
tree.pack()
button1 = tk.Button(text="Display data", command=View)
button1.pack()
root.mainloop()
How can I make it print/get the data after clearing the last fetched data?
Regards,
You can do a simple check, if there are items inside and then delete all the items, and if not insert, like:
def View():
if len(tree.get_children()): # If there are items inside
tree.delete(*tree.get_children()) # Delete all the items
else:
# Paste the rest of code
You can also define a flag and then check if data is inserted, and proceed accordingly, like:
inserted = False # Initially False
def View():
if inserted:
tree.delete(*tree.get_children())
inserted = False # Set it to not inserted
if not inserted: # Let this get triggered
# Same code
for row in rows:
print(row)
tree.insert("", tk.END, values=row)
mydb.close()
inserted = True # Set it to true.
I am trying to create a button where you can delete a record selected using trv.bind. I can select fine as I already tried using print to display the OID when selecting but when I add a delete function, it does nothing and gives me no errors. From my understanding I am selecting the specific row through the OID but my function does not delete. The query is not executing.
I made a sample code that mirrors mine.
import tkinter
from tkinter import *
from tkinter import ttk, LabelFrame, StringVar
import tkinter.messagebox
import sqlite3
#cursor
conn = sqlite3.connect('newtest.db')
#cursor is needed for sql functions
c = conn.cursor()
top = tkinter.Tk()
q = StringVar()
t1 = StringVar()
t2 = StringVar()
#this grabs each ID
def getrows(event):
rowid = trv.identify_row(event.y)
item = trv.item(trv.focus())
t1.set(item['values'][0])
t2.set(item['values'][1])
def pdelete():
oid = t1.get()
query = "DELETE FROM products WHERE oid = "+oid
c.execute(query)
conn.commit()
def update(show):
trv.delete(*trv.get_children())
for i in show:
trv.insert("", 'end', values=i)
return show
conn.commit()
def query_database():
query = "SELECT oid, pdesc from products"
conn = sqlite3.connect('newtest.db')
c = conn.cursor()
c.execute(query)
show = c.fetchall()
return show
box4 = LabelFrame(top, text="Products Summary")
box4.pack (fill="both", expand="yes", padx=20, pady=10)
trv = ttk.Treeview(box4, column=(1,2), show="headings", height="20")
style=ttk.Style(trv)
style.configure('Treeview', rowheight=20)
trv.pack(side=LEFT)
trv.heading(1, text="Product ID")
trv.heading(2, text="Product Description")
conn = sqlite3.connect('newtest.db')
query = "SELECT oid, pdesc from products"
c.execute(query)
show = c.fetchall()
update(show)
#deletebutton
btn6 = ttk.Button(box4, text='Delete', command=pdelete)
btn6.pack(side=RIGHT)
#select
trv.bind('<Double 1>', getrows)
top.title("deletetest")
top.geometry("1500x1200")
top.mainloop()
Am trying to update sqlite3 db selected in tkinter treeview, am able to insert the row of the treeview selected in the entry widget but when i update the record selected it updates all the records in the sqlite3 db. I need your help to update only the record selected in the treeview but not all the records in the sqlite3 db.
from tkinter import ttk
import tkinter as tk
import sqlite3
def connect():
conn = sqlite3.connect("TRIAL.db")
cur = conn.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS profile(id INTEGER PRIMARY KEY,
First TEXT, Surname TEXT)")
conn.commit()
conn.close()
def Update():
data1 = first_text.get()
data2 = surname_text.get()
for selected in tree.selection():
e1.insert(0, selected)
e2.insert(0, selected)
conn = sqlite3.connect("TRIAL.db")
cur = conn.cursor()
cur.execute("UPDATE profile SET First=?, Surname=?", (data1, data2))
conn.commit()
conn.close()
def get_selected_row(event):
print(tree.selection()) # this will print the names of the selected rows
for nm in tree.selection():
content = tree.item(nm, 'values')
e1.insert(tk.END, content[1])
e2.insert(tk.END, content[2]) # this will insert in the entry after
connect() # this to create the db
root = tk.Tk()
root.geometry("400x400")
# this will hide the first column
tree= ttk.Treeview(root, column=("column1", "column2", "column3"),
show='headings')
tree.heading("#1", text="NUMBER")
tree.heading("#2", text="FIRST NAME")
tree.heading("#3", text="SURNAME")
tree.pack()
tree.bind("<<TreeviewSelect>>", get_selected_row)
first_text = tk.StringVar()
e1 = tk.Entry(root, textvariable=first_text)
e1.pack()
surname_text = tk.StringVar()
e2 = tk.Entry(root, textvariable=surname_text)
e2.pack()
b2 = tk.Button(text="EDIT PARTICULAR DATA", command=Update)
b2.pack(side=tk.BOTTOM)
root.mainloop()
The issue here is that you don't tell the db which record to update:
cur.execute("UPDATE profile SET First=?, Surname=?", (data1, data2))
so all records are updated. You need to add the record id:
cur.execute("UPDATE profile SET First=?, Surname=? WHERE ID =?", (data1, data2, tree.set(selected, '#1')))
I found the answer on the website https://www.tutorialspoint.com/sqlite/sqlite_update_query.htm.