用Python和Tkinter标准模块建立密码管理器
创建一个简单的密码管理器应用程序,帮助用户存储和管理他们的密码。使用Python的tkinter模块来创建一个图形用户界面(GUI)。
本程序支持 添加、查看、搜索、复制、修改、删除 功能。
本程序使用 SQLite建立 passwords.db用以保存密码信息。
通过强制所有密码相关操作以字符串形式处理,解决前导零丢失问题。
Base64是Python的标准库模块之一,用于进行Base64编码和解码操作。Base64并不是一种加密算法,而是一种编码方案,它不适合用于保护敏感信息,在此用于简化演示。如果需要保护敏感信息(如密码),应使用真正的加密算法(如 AES)。
运行效果:

源码如下:
import tkinter as tk
from tkinter import ttk, messagebox
import sqlite3
import base64
# 加密函数(强制输入为字符串)
def encrypt(password):
    password_str = str(password)  # 强制转为字符串
    return base64.b64encode(password_str.encode()).decode()
# 解密函数(直接返回字符串)
def decrypt(encrypted_password):
    decrypted_bytes = base64.b64decode(encrypted_password.encode())
    return decrypted_bytes.decode()  # 直接返回字符串
# 初始化数据库
def init_db():
    conn = sqlite3.connect("passwords.db")
    cursor = conn.cursor()
    cursor.execute("""
        CREATE TABLE IF NOT EXISTS passwords (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            project TEXT NOT NULL,
            username TEXT NOT NULL,
            password TEXT NOT NULL
        )
    """)
    conn.commit()
    conn.close()
# 添加密码(强制密码为字符串)
def add_password():
    project = project_entry.get()
    username = username_entry.get()
    password = password_entry.get()
    if not project or not username or not password:
        messagebox.showwarning("输入错误", "请填写所有字段!")
        return
    encrypted_password = encrypt(str(password))  # 强制转为字符串
    conn = sqlite3.connect("passwords.db")
    cursor = conn.cursor()
    cursor.execute("INSERT INTO passwords (project, username, password) VALUES (?, ?, ?)",
                   (project, username, encrypted_password))
    conn.commit()
    conn.close()
    project_entry.delete(0, tk.END)
    username_entry.delete(0, tk.END)
    password_entry.delete(0, tk.END)
    view_passwords()
# 查看密码(显示时强制转为字符串)
def view_passwords():
    for row in tree.get_children():
        tree.delete(row)
    conn = sqlite3.connect("passwords.db")
    cursor = conn.cursor()
    cursor.execute("SELECT id, project, username, password FROM passwords")
    rows = cursor.fetchall()
    conn.close()
    for row in rows:
        id, project, username, encrypted_password = row
        decrypted_password = decrypt(encrypted_password)
        tree.insert("", tk.END, values=(id, project, username, str(decrypted_password)))
# 搜索密码
def search_password():
    search_term = search_entry.get()
    for row in tree.get_children():
        tree.delete(row)
    conn = sqlite3.connect("passwords.db")
    cursor = conn.cursor()
    cursor.execute("SELECT id, project, username, password FROM passwords WHERE project LIKE ?",
                   (f"%{search_term}%",))
    rows = cursor.fetchall()
    conn.close()
    for row in rows:
        id, project, username, encrypted_password = row
        decrypted_password = decrypt(encrypted_password)
        tree.insert("", tk.END, values=(id, project, username, str(decrypted_password)))
# 复制密码(关键修复:直接从数据库获取)
def copy_password():
    selected_item = tree.selection()
    if not selected_item:
        messagebox.showwarning("未选择", "请选择一条记录!")
        return
    # 获取选中行的项目名和用户名
    item = tree.item(selected_item)
    project = item["values"][1]
    username = item["values"][2]
    # 直接从数据库查询原始密码
    conn = sqlite3.connect("passwords.db")
    cursor = conn.cursor()
    cursor.execute("SELECT password FROM passwords WHERE project = ? AND username = ?", (project, username))
    row = cursor.fetchone()
    conn.close()
    if row:
        encrypted_password = row[0]
        decrypted_password = decrypt(encrypted_password)
        root.clipboard_clear()
        root.clipboard_append(str(decrypted_password))  # 强制转为字符串
        messagebox.showinfo("复制成功", "密码已复制到剪贴板!")
    else:
        messagebox.showerror("错误", "未找到密码!")
# 删除记录
def delete_password():
    selected_item = tree.selection()
    if not selected_item:
        messagebox.showwarning("未选择", "请选择一条记录!")
        return
    item = tree.item(selected_item)
    record_id = item["values"][0]
    confirm = messagebox.askyesno("确认删除", "确定要删除这条记录吗?")
    if not confirm:
        return
    conn = sqlite3.connect("passwords.db")
    cursor = conn.cursor()
    cursor.execute("DELETE FROM passwords WHERE id = ?", (record_id,))
    conn.commit()
    conn.close()
    view_passwords()
# 修改记录(关键修复:输入框获取值强制为字符串)
def edit_password():
    selected_item = tree.selection()
    if not selected_item:
        messagebox.showwarning("未选择", "请选择一条记录!")
        return
    item = tree.item(selected_item)
    record_id = item["values"][0]
    # 直接从数据库获取原始密码
    conn = sqlite3.connect("passwords.db")
    cursor = conn.cursor()
    cursor.execute("SELECT project, username, password FROM passwords WHERE id = ?", (record_id,))
    project, username, encrypted_password = cursor.fetchone()
    conn.close()
    current_password = decrypt(encrypted_password)
    edit_window = tk.Toplevel(root)
    edit_window.title("修改记录")
    edit_window.geometry("300x200")
    # 项目名
    ttk.Label(edit_window, text="项目名:").grid(row=0, column=0, padx=5, pady=5)
    project_entry = ttk.Entry(edit_window, width=25)
    project_entry.grid(row=0, column=1, padx=5, pady=5)
    project_entry.insert(0, project)
    # 用户名
    ttk.Label(edit_window, text="用户名:").grid(row=1, column=0, padx=5, pady=5)
    username_entry = ttk.Entry(edit_window, width=25)
    username_entry.grid(row=1, column=1, padx=5, pady=5)
    username_entry.insert(0, username)
    # 密码(关键:输入框直接使用字符串,避免转换)
    ttk.Label(edit_window, text="密码:").grid(row=2, column=0, padx=5, pady=5)
    password_entry = ttk.Entry(edit_window, width=25)
    password_entry.grid(row=2, column=1, padx=5, pady=5)
    password_entry.insert(0, str(current_password))  # 强制转为字符串
    def save_edit():
        new_project = project_entry.get()
        new_username = username_entry.get()
        new_password = password_entry.get()  # 直接获取字符串
        if not new_project or not new_username or not new_password:
            messagebox.showwarning("输入错误", "请填写所有字段!")
            return
        encrypted_password = encrypt(str(new_password))  # 加密前确保为字符串
        conn = sqlite3.connect("passwords.db")
        cursor = conn.cursor()
        cursor.execute("""
            UPDATE passwords 
            SET project = ?, username = ?, password = ?
            WHERE id = ?
        """, (new_project, new_username, encrypted_password, record_id))
        conn.commit()
        conn.close()
        messagebox.showinfo("成功", "记录已更新!")
        edit_window.destroy()
        view_passwords()
    save_button = ttk.Button(edit_window, text="保存", command=save_edit)
    save_button.grid(row=3, column=0, columnspan=2, pady=10)
# 初始化数据库
init_db()
# 创建主窗口
root = tk.Tk()
root.title("密码管理器")
root.geometry("800x600")
# 输入区域
input_frame = ttk.LabelFrame(root, text="添加密码")
input_frame.pack(fill=tk.X, padx=10, pady=10)
ttk.Label(input_frame, text="项目名:").grid(row=0, column=0, padx=5, pady=5)
project_entry = ttk.Entry(input_frame, width=30)
project_entry.grid(row=0, column=1, padx=5, pady=5)
ttk.Label(input_frame, text="用户名:").grid(row=1, column=0, padx=5, pady=5)
username_entry = ttk.Entry(input_frame, width=30)
username_entry.grid(row=1, column=1, padx=5, pady=5)
ttk.Label(input_frame, text="密码:").grid(row=2, column=0, padx=5, pady=5)
password_entry = ttk.Entry(input_frame, width=30)
password_entry.grid(row=2, column=1, padx=5, pady=5)
add_button = ttk.Button(input_frame, text="添加", command=add_password)
add_button.grid(row=3, column=0, columnspan=2, pady=10)
# 搜索区域
search_frame = ttk.LabelFrame(root, text="搜索密码")
search_frame.pack(fill=tk.X, padx=10, pady=10)
ttk.Label(search_frame, text="搜索项目名:").grid(row=0, column=0, padx=5, pady=5)
search_entry = ttk.Entry(search_frame, width=30)
search_entry.grid(row=0, column=1, padx=5, pady=5)
search_button = ttk.Button(search_frame, text="搜索", command=search_password)
search_button.grid(row=0, column=2, padx=5, pady=5)
show_all_button = ttk.Button(search_frame, text="全部显示", command=view_passwords)
show_all_button.grid(row=0, column=3, padx=5, pady=5)
# 密码列表
tree_frame = ttk.LabelFrame(root, text="密码列表")
tree_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
columns = ("id", "project", "username", "password")
tree = ttk.Treeview(tree_frame, columns=columns, show="headings")
tree.heading("project", text="项目名")
tree.heading("username", text="用户名")
tree.heading("password", text="密码")
tree.column("id", width=0, stretch=tk.NO)  # 隐藏ID列
tree.column("password", width=150)
tree.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
# 操作按钮区域
button_frame = ttk.Frame(tree_frame)
button_frame.pack(pady=10)
copy_button = ttk.Button(button_frame, text="复制密码", command=copy_password)
copy_button.pack(side=tk.LEFT, padx=5)
edit_button = ttk.Button(button_frame, text="修改记录", command=edit_password)
edit_button.pack(side=tk.LEFT, padx=5)
delete_button = ttk.Button(button_frame, text="删除记录", command=delete_password)
delete_button.pack(side=tk.LEFT, padx=5)
# 首次加载显示数据
view_passwords()
# 运行主循环
root.mainloop()
 
 
 
                


















