如何在Python Tkinter中仅删除单行?程序重启后数据全丢求助
问题根源
你的核心问题出在delete_item方法里的SQL语句:
self.c.execute("DELETE FROM books")
这行代码会删除books表中的所有数据,而不是你选中的那一行。界面上只删除选中项是因为你单独调用了self.list_box.delete(item),但数据库里的所有数据都被清空了,所以重启程序后看不到任何数据。
修复步骤
1. 修正删除逻辑,只删除选中的记录
修改delete_item方法,先获取选中的行数据,再根据这些数据删除数据库中对应的记录(这里用ISBN作为唯一标识,也可以用所有字段匹配):
def delete_item(self): selected_indices = self.list_box.curselection() # 倒序删除,避免索引移位导致的错误 for idx in reversed(selected_indices): # 获取选中的行数据 selected_row = self.list_box.get(idx) # 从界面删除条目 self.list_box.delete(idx) # 删除数据库中对应记录 self.c.execute("DELETE FROM books WHERE isbn = ?", (selected_row[3],)) self.bookInfodb.commit()
倒序删除的原因:如果从前往后删,删除第一个元素后,后面的元素索引会前移,导致后续索引指向错误的条目。
2. 修复addData方法的参数冗余问题
你的addData方法定义了参数但实际未使用,直接调用控件的get()方法即可,同时添加列表刷新逻辑,避免手动重启程序才能看到新数据:
def addData(self): self.c.execute( "INSERT INTO books VALUES (?,?,?,?)", ( self.title.get(), self.years.get(), self.author.get(), self.isbn.get())) self.bookInfodb.commit() # 清空列表后重新加载数据,刷新界面 self.list_box.delete(0, END) self.fetch()
对应的按钮命令也要简化:
save_button = Button( self, text=" save ", command=self.addData)
3. 确保程序退出时关闭数据库连接
添加窗口关闭回调,避免数据写入不完整:
在__init__方法最后添加:
self.protocol("WM_DELETE_WINDOW", self.on_closing)
新增on_closing方法:
def on_closing(self): self.bookInfodb.close() self.destroy()
完整修正后的代码
import sqlite3 from tkinter import * from tkinter import ttk class root(Tk): def __init__(self): super().__init__() self.bookInfodb = sqlite3.connect("test.db") self.c = self.bookInfodb.cursor() self.c.execute( "CREATE TABLE IF NOT EXISTS books (title TEXT, author TEXT, year TEXT, isbn TEXT)") self.bookInfodb.commit() self.title("book info") self.minsize(500, 400) self.configure(background="gray") self.datas() self.fetch() # 绑定窗口关闭事件 self.protocol("WM_DELETE_WINDOW", self.on_closing) def fetch(self): self.c.execute("SELECT * FROM books") rows = self.c.fetchall() for row in rows: self.list_box.insert(END, row) def delete_item(self): selected_indices = self.list_box.curselection() # 倒序删除避免索引移位 for idx in reversed(selected_indices): selected_row = self.list_box.get(idx) self.list_box.delete(idx) # 根据ISBN删除对应记录 self.c.execute("DELETE FROM books WHERE isbn = ?", (selected_row[3],)) self.bookInfodb.commit() def addData(self): self.c.execute( "INSERT INTO books VALUES (?,?,?,?)", ( self.title.get(), self.years.get(), self.author.get(), self.isbn.get())) self.bookInfodb.commit() # 刷新列表 self.list_box.delete(0, END) self.fetch() def datas(self): self.title = StringVar() self.titleEntry = ttk.Label(self, text="title") self.titleEntry.place(x=41, y=10) entry = Entry(self, textvariable=self.title) entry.place(x=66, y=10) self.years = StringVar() self.yearsEntry = ttk.Label(self, text="years") self.yearsEntry.place(x=269, y=10) entry2 = Entry(self, textvariable=self.years) entry2.place(x=300.5, y=10.2) self.author = StringVar() self.authorEntry = ttk.Label(self, text="author") self.authorEntry.place(x=40, y=51) entry3 = Entry(self, textvariable=self.author) entry3.place(x=80, y=51) self.isbn = StringVar() self.isbnEntry = ttk.Label(self, text="isbn") self.isbnEntry.place(x=270, y=52) entry_iv = Entry(self, textvariable=self.isbn) entry_iv.place(x=297, y=52) self.list_box = Listbox(self, height=10, width=50) self.list_box.place(x=85, y=200) save_button = Button( self, text=" save ", command=self.addData) save_button.place(x=66, y=150) delete_button = Button(self, text="delete", command=self.delete_item) delete_button.place(x=215, y=150) def on_closing(self): self.bookInfodb.close() self.destroy() windows = root() windows.mainloop()
内容的提问来源于stack exchange,提问作者user19762805
相关产品推荐
相关产品推荐

