Python+SQLite3+Tkinter登录验证异常:终端输出不符合预期
管理员登录验证代码问题排查与修复
问题现象
输入正确的用户名和密码时,终端同时输出“login success”和“Access Denied”;输入错误凭据时,终端两次输出“Access Denied”(数据库admins表仅有2条管理员数据)。
问题根源
- 代码执行顺序错误:
print("login sucess")写在break语句之后,这条代码永远不会被执行。 - 循环逻辑缺陷:遍历所有管理员数据时,每遇到一条不匹配的记录就输出“Access Denied”:
- 输入正确凭据时,若匹配的不是第一条数据,前面不匹配的条目会触发一次“Access Denied”;
- 输入错误凭据时,两条数据都不匹配,因此会输出两次“Access Denied”。
- 查询效率低下:当前代码查询所有管理员数据再遍历,没必要,直接通过用户名查询更高效。
修复后的代码
import sqlite3 from tkinter import * def clear_fields(): enter1.delete(0, END) enter2.delete(0, END) conn = sqlite3.connect("main.db") c = conn.cursor() c.execute( """CREATE TABLE IF NOT EXISTS admins( admin_id INTEGER PRIMARY KEY, name text, password text )""" ) conn.commit() def pass_check(): username = enter1.get().strip() password = enter2.get().strip() # 直接根据用户名查询,避免遍历所有数据 c.execute("SELECT password FROM admins WHERE name = ?", (username,)) result = c.fetchone() if result and result[0] == password: print("login success") else: print("Access Denied") root = Tk() root.geometry("250x180+550+200") root.resizable(False, False) root.title("Admin Login") try: root.iconbitmap("login.ico") except: # 避免图标文件不存在导致报错 pass labl1 = Label(text="User name: ") labl1.place(x=10, y=10) labl2 = Label(text="Password: ") labl2.place(x=10, y=70) enter1 = Entry() enter1.place(x=80, y=10) enter2 = Entry(show="*") enter2.place(x=80, y=70) ok_btn = Button(text="Login", width=6, height=1, command=pass_check) ok_btn.place(x=150, y=100) clear_btn = Button(text="Clear", width=6, height=1, command=clear_fields) clear_btn.place(x=80, y=100) root.mainloop()
修复说明
- 优化查询逻辑:通过
WHERE name = ?直接查询目标用户,既提升效率,又避免遍历所有数据导致的多次输出问题。 - 统一结果输出:循环结束后根据查询结果判断,只会输出一次成功或失败信息。
- 增加异常处理:对图标文件加载增加异常捕获,避免文件不存在导致程序崩溃。
- 去除冗余代码:删除了无用的
usr = ""和pas = ""变量,以及多余的enter2.config()调用。
内容的提问来源于stack exchange,提问作者Whhw31
相关产品推荐
相关产品推荐

