You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 18:45:42