问题
I've got a problem w with my program "phonebook" with sqlite3. There are 2 functions doesn't work properly with treeview in tkinter. When I try to update one selected row it updated all rows/records in sqlite but in treeview is correctly one updated record, and when I try delete one selected row it deletes all datas from sqlite whereas in treeview is deleted one selected row. I suppose there is no connection between treeview and sqlite3. I don't know what the problem is.
from tkinter import*
import sqlite3
from sqlite3 import OperationalError
from tkinter import ttk
from tkinter import messagebox
root=Tk()
root.title("Phonebook")
root.geometry("460x600")
one = StringVar()
two = StringVar()
three = StringVar()
def create_sql():
conn = sqlite3.connect("phone_book.db")
cur = conn.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS profile (First TEXT, Surname TEXT, phone_number TEXT)")
conn.commit()
conn.close()
def get_row(event):
try:
cursor = tree.focus()
content = tree.item(cursor)
row = content["values"]
one.set(row[0])
two.set(row[1])
three.set(row[2])
except IndexError:
pass
def update_selcted_row():
data1 = one.get()
data2 = two.get()
data3 = three.get()
conn = sqlite3.connect("phone_book.db")
cur = conn.cursor()
cur.execute("""UPDATE profile SET First=?, Surname=?, phone_number=? """, (data1, data2, data3))
conn.commit()
conn.close()
def del_sel():
data1 = one.get()
data2 = two.get()
data3 = three.get()
try:
selected_item = tree.selection()[0]
tree.delete(selected_item)
except IndexError:
pass
conn = sqlite3.connect("phone_book.db")
c = conn.cursor()
c.execute("DELETE FROM profile WHERE First=? AND Surname=? AND phone_number=?",(data1, data2, data3))
conn.commit()
conn.close()
#Labels
lb= Label(root,text="Firstname:",font=("calibri",15))
lb.grid(row=0,column=0,padx=10,pady=5,sticky=E)
lb1= Label(root,text="Lastname: ",font=("calibri",15))
lb1.grid(row=1,column=0,padx=10,pady=5,sticky=E)
lb2= Label(root,text="Phone number",font=("calibri",15))
lb2.grid(row=2,column=0,padx=10,pady=5,sticky=E)
#buttons
but1 = Button(root,text="Update\nselected row",width=13,command=update_selected_row)
but1.grid(row=6,column=0,pady=5)
but4 = Button(root,text="Delete\nselected",width=13,command=del_sel)
but4.grid(row=7,column=0,pady=5)
#entries
e = Entry(root,bd=2,textvariable=one)
e.grid(row=0,column=1,padx=10,pady=5)
e1 = Entry(root,bd=2,textvariable=two)
e1.grid(row=1,column=1,padx=10,pady=5)
e2 = Entry(root,bd=2,textvariable=three)
e2.grid(row=2,column=1,padx=10,pady=5)
#treeview
tree = ttk.Treeview(root,height=10)
tree["columns"]=("one","two","three")
tree.column("one",width=120)
tree.column("two",width=130)
tree.column("three",width=160)
tree.heading("one", text="Imię")
tree.heading("two", text="Nazwisko")
tree.heading("three", text="Nr Telefonu")
tree["show"]="headings"
tree.grid(row=4,column=0,columnspan=6,padx=20)
tree.bind("<ButtonRelease-1>",get_row)
create_sql()
root.mainloop()
回答1:
You need a WHERE clause in UPDATE
statement:
def update_selected_row():
# original data
cursor = tree.focus()
content = tree.item(cursor)
row = content["values"]
# new data
data1 = one.get()
data2 = two.get()
data3 = three.get()
# update database
conn = sqlite3.connect("phone_book.db")
cur = conn.cursor()
cur.execute("""UPDATE profile SET First=?, Surname=?, phone_number=? WHERE First=? AND Surname=? AND phone_number=?""",
(data1, data2, data3, row[0], row[1], row[2]))
conn.commit()
conn.close()
# update treeview
tree.item(cursor, values=(data1, data2, data3))
EDIT: update code with unique id field in database table:
from tkinter import*
import sqlite3
from sqlite3 import OperationalError
from tkinter import ttk
from tkinter import messagebox
root=Tk()
root.title("Phonebook")
root.geometry("460x600")
one = StringVar()
two = StringVar()
three = StringVar()
rowid = StringVar()
def create_sql():
conn = sqlite3.connect("phone_book.db")
cur = conn.cursor()
# added id field
cur.execute("CREATE TABLE IF NOT EXISTS profile (id INTEGER PRIMARY KEY, First TEXT, Surname TEXT, phone_number TEXT)")
conn.commit()
cur.execute("SELECT * FROM profile")
for rec in cur:
tree.insert('', 'end', iid=rec[0], values=rec[1:])
conn.close()
def get_row(event):
try:
cursor = tree.focus()
content = tree.item(cursor)
row = content["values"]
rowid.set(cursor)
one.set(row[0])
two.set(row[1])
three.set(row[2])
except IndexError:
pass
def add_record():
data1 = one.get()
data2 = two.get()
data3 = three.get()
conn = sqlite3.connect("phone_book.db")
cur = conn.cursor()
cur.execute("""INSERT INTO profile VALUES (NULL, ?, ?, ?)""", (data1, data2, data3))
conn.commit()
conn.close()
# update treeview
tree.insert('', 'end', iid=cur.lastrowid, values=(data1, data2, data3))
def update_selected_row():
id = rowid.get()
# new data
data1 = one.get()
data2 = two.get()
data3 = three.get()
conn = sqlite3.connect("phone_book.db")
cur = conn.cursor()
cur.execute("""UPDATE profile SET First=?, Surname=?, phone_number=? WHERE id=?""", (data1, data2, data3, id,))
conn.commit()
conn.close()
# update treeview
tree.item(id, values=(data1, data2, data3))
def del_sel():
id = rowid.get()
data1 = one.get()
data2 = two.get()
data3 = three.get()
try:
selected_item = tree.selection()[0]
tree.delete(selected_item)
except IndexError:
pass
conn = sqlite3.connect("phone_book.db")
c = conn.cursor()
c.execute("DELETE FROM profile WHERE id=?", (id,))
conn.commit()
conn.close()
#Labels
lb= Label(root,text="Firstname:",font=("calibri",15))
lb.grid(row=0,column=0,padx=10,pady=5,sticky=E)
lb1= Label(root,text="Lastname: ",font=("calibri",15))
lb1.grid(row=1,column=0,padx=10,pady=5,sticky=E)
lb2= Label(root,text="Phone number",font=("calibri",15))
lb2.grid(row=2,column=0,padx=10,pady=5,sticky=E)
#buttons
but1 = Button(root,text="Update\nselected row",width=13,command=update_selected_row)
but1.grid(row=6,column=0,pady=5)
but4 = Button(root,text="Delete\nselected",width=13,command=del_sel)
but4.grid(row=7,column=0,pady=5)
but5 = Button(root,text="Add\nRecord",width=13,command=add_record)
but5.grid(row=8,column=0,pady=5)
#entries
e = Entry(root,bd=2,textvariable=one)
e.grid(row=0,column=1,padx=10,pady=5)
e1 = Entry(root,bd=2,textvariable=two)
e1.grid(row=1,column=1,padx=10,pady=5)
e2 = Entry(root,bd=2,textvariable=three)
e2.grid(row=2,column=1,padx=10,pady=5)
#treeview
tree = ttk.Treeview(root,height=10)
tree["columns"]=("one","two","three")
tree.column("one",width=120)
tree.column("two",width=130)
tree.column("three",width=160)
tree.heading("one", text="Imię")
tree.heading("two", text="Nazwisko")
tree.heading("three", text="Nr Telefonu")
tree["show"]="headings"
tree.grid(row=4,column=0,columnspan=6,padx=20)
tree.bind("<ButtonRelease-1>",get_row)
create_sql()
root.mainloop()
来源:https://stackoverflow.com/questions/63011692/two-functions-dont-work-properly-in-tkinter-python-with-sqlite3