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

如何实现可保存用户输入的按钮(基于Tkinter与SQLite3)

实现Tkinter程序的SQLite3数据保存功能

以下是修改后的完整代码,已实现两个「Save」按钮的数据库保存功能,适配你的需求:

import tkinter as tk
from tkinter import messagebox
import sqlite3 as sql

# 初始化数据库,创建必要的表
def init_db():
    conn = sql.connect('user_data.db')
    cursor = conn.cursor()
    # 创建分类表
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS catalogs (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            name TEXT UNIQUE NOT NULL
        )
    ''')
    # 创建账号密码表,关联分类
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS credentials (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            catalog_id INTEGER NOT NULL,
            login TEXT NOT NULL,
            password TEXT NOT NULL,
            FOREIGN KEY (catalog_id) REFERENCES catalogs(id)
        )
    ''')
    conn.commit()
    conn.close()

# 保存分类到数据库(主窗口Save按钮功能)
def save_catalogs():
    conn = sql.connect('user_data.db')
    cursor = conn.cursor()
    # 先清空现有分类(可选,若要保留历史可删除此句)
    cursor.execute('DELETE FROM catalogs')
    # 获取列表框所有分类
    catalogs = catalogs_listbox.get(0, tk.END)
    for catalog in catalogs:
        try:
            cursor.execute('INSERT INTO catalogs (name) VALUES (?)', (catalog,))
        except sql.IntegrityError:
            # 避免重复分类插入报错
            pass
    conn.commit()
    conn.close()
    messagebox.showinfo('提示', '分类已保存到数据库')

# 保存账号密码到对应分类(子窗口Save按钮功能)
def save_credentials(catalog_name, login_entry, password_entry, window):
    login = login_entry.get().strip()
    password = password_entry.get().strip()
    if not login or not password:
        messagebox.showinfo('提示', '登录名和密码不能为空')
        return
    
    conn = sql.connect('user_data.db')
    cursor = conn.cursor()
    # 获取对应分类的ID
    cursor.execute('SELECT id FROM catalogs WHERE name = ?', (catalog_name,))
    result = cursor.fetchone()
    if not result:
        # 如果分类不存在,先插入分类
        cursor.execute('INSERT INTO catalogs (name) VALUES (?)', (catalog_name,))
        catalog_id = cursor.lastrowid
    else:
        catalog_id = result[0]
    # 插入账号密码
    cursor.execute('INSERT INTO credentials (catalog_id, login, password) VALUES (?, ?, ?)',
                  (catalog_id, login, password))
    conn.commit()
    conn.close()
    messagebox.showinfo('提示', '账号密码已保存')
    window.destroy()

win = tk.Tk()
win.title('数据保存器')
win.geometry('390x310')
win.resizable(False, False)

# 初始化数据库
init_db()

def delete_catalog():
    selection = catalogs_listbox.curselection()
    try:
        catalogs_listbox.delete(selection[0])
    except IndexError:
        messagebox.showinfo('注意!', '请选择要删除的分类')

def add_catalog():
    new_catalog = catalog_entry.get().strip()
    if len(new_catalog) > 0:
        catalogs_listbox.insert(0, new_catalog)
        catalog_entry.delete(0, tk.END)
    else:
        messagebox.showinfo('注意!', '请输入分类名称!')

intro = tk.Label(text='')
intro.configure(font=('Times New Roman', 11))
intro.place(x=5, y=5)

catalog_entry = tk.Entry(width=21)
catalog_entry.configure(font=('Times New Roman', 15))
catalog_entry.place(x=51, y=30)
add_catalog_btn = tk.Button(text="添加", width=9, command=add_catalog)
add_catalog_btn.place(y=30, x=268)

catalogs_listbox = tk.Listbox(width=29, height=9)
catalogs_listbox.configure(font=('Times New Roman', 15))
catalogs_listbox.place(x=49, y=60)

def on_select(event):
    widget = event.widget
    selection = widget.curselection()
    if not selection:
        return
    i = int(selection[0])
    value = widget.get(i)
    
    data_window = tk.Toplevel()  # 用Toplevel替代Tk,避免多主循环异常
    data_window.title(f'{value}的账号数据')
    data_window.geometry('390x65')
    data_window.resizable(False, False)

    login_label = tk.Label(master=data_window, text='登录名')
    login_label.place(x=15, y=5)
    login_entry = tk.Entry(master=data_window, width=30)
    login_entry.place(x=100, y=5)

    password_label = tk.Label(master=data_window, text='密码')
    password_label.place(x=15, y=35)
    password_entry = tk.Entry(master=data_window, width=30)
    password_entry.place(x=100, y=35)

    # 绑定保存按钮功能
    save_datas = tk.Button(master=data_window, text='保存', 
                          command=lambda: save_credentials(value, login_entry, password_entry, data_window))
    save_datas.place(x=300, y=15)

catalogs_listbox.bind('<<ListboxSelect>>', on_select)

# 主窗口保存按钮绑定功能
save_program = tk.Button(master=win, text='保存分类', command=save_catalogs)
save_program.place(x=200, y=278)

scrollbar = tk.Scrollbar(orient=tk.VERTICAL, command=catalogs_listbox.yview)
scrollbar.grid_forget()
catalogs_listbox["yscrollcommand"] = scrollbar.set

delete_catalog_btn = tk.Button(text="删除", command=delete_catalog)
delete_catalog_btn.configure(font=('Times New Roman', 10))
delete_catalog_btn.place(x=286, y=278)

win.mainloop()

关键修改说明:

  • 数据库初始化:启动程序自动创建user_data.db文件,以及catalogs(分类表)和credentials(账号密码表),确保数据存储结构合法。
  • 子窗口Save按钮:获取登录名和密码后,关联当前选中分类插入数据库;若分类未提前保存,会自动添加到分类表。
  • 主窗口Save按钮:将列表框中所有分类保存到数据库,覆盖原有分类记录(若需保留历史,可删除清空分类的语句)。
  • 细节优化:将子窗口改为tk.Toplevel()避免多主循环异常;增加输入为空校验;处理重复分类插入的异常。

内容的提问来源于stack exchange,提问作者pomalllka

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 01:52:07