一、源代码
# gui_user_management.py
try:
# 导入模块
from tkinter import *
from tkinter.messagebox import *
import sqlite3
from traceback import print_tb
from datetime import datetime
# 创建并设置主窗口
root = Tk()
root.resizable(False, False)
systitle = '用户注册信息管理系统'
root.title(systitle)
curWidth, curHeight = 500, 300
scnWidth, scnHeight = root.maxsize()
geocnf = '%dx%d+%d+%d' % (curWidth, curHeight,
(scnWidth - curWidth) / 2, (scnHeight - curHeight) / 2)
root.geometry(geocnf)
# 设置主窗口背景
pic = PhotoImage(file='background.gif')
label1 = Label(image=pic)
label1.place(x=0, y=0)
# 功能界面
mainframe = LabelFrame()
mainframe.pack()
# 数据库名
dbfile = 'userdb.dat'
# 异常日志文件名
logfile = 'user_management_error.log'
# 获取数据库连接
def getconn():
try:
import sqlite3
conn = sqlite3.connect(dbfile)
return conn
except Exception as ex:
print('数据库访问出错:', ex)
raise ex # 向外传递异常,以便统一写入日志
# 显示全部用户
def showall():
global mainframe
conn = getconn()
cur = conn.execute('select * from user')
users = cur.fetchall()
conn.close()
mainframe.destroy()
if len(users) == 0:
showwarning(systitle, '当前没有注册用户!')
else:
mainframe = LabelFrame(text='全部注册用户')
mainframe.pack(anchor=CENTER, padx=5, pady=5, ipadx=5, ipady=5)
mainframe.columnconfigure(1, minsize=80)
mainframe.columnconfigure(2, minsize=200)
mainframe.columnconfigure(3, minsize=200)
Label(mainframe, text='序号', font=('宋体', 12, 'bold'),
bd=1, relief=SOLID).grid(row=1, column=1, sticky=N + E + S + W)
Label(mainframe, text='用户名', font=('宋体', 12, 'bold'),
bd=1, relief=SOLID).grid(row=1, column=2, sticky=N + E + S + W)
Label(mainframe, text='密码', font=('宋体', 12, 'bold'),
bd=1, relief=SOLID).grid(row=1, column=3, sticky=N + E + S + W)
rn = 2 # 行号
for user in users:
cn = 1 # 列号
Label(mainframe, text=str(rn - 1), font=('宋体', 12), bd=1,
relief=SOLID).grid(row=rn, column=cn, sticky=N + E + S + W)
for field in user:
cn = cn + 1
Label(mainframe, text=str(field), font=('宋体', 12), bd=1,
relief=SOLID).grid(row=rn, column=cn, sticky=N + E + S + W)
rn = rn + 1
# 重置数据库
def resetdb():
global mainframe
mainframe.destroy()
msg = '将删除全部注册用户!\n请你确认是否要继续?'
if askokcancel(systitle, msg):
import os
if os.path.exists(dbfile):
os.remove(dbfile)
showinfo(systitle, '系统重置数据库!')
else:
showinfo(systitle, '系统创建数据库!')
conn = getconn()
conn.execute('create table user(username text primary key, password text)')
conn.close()
# 查找用户名是否存在
def find(username):
conn = getconn()
cur = conn.execute('select * from user where username = ? ', (username,))
users = cur.fetchall()
conn.close()
if len(users) > 0:
return True
else:
return False
# 添加用户
def adduser():
global mainframe
mainframe.destroy()
mainframe = LabelFrame(text='添加新用户')
mainframe.pack(anchor=CENTER, pady=20, ipadx=5, ipady=5)
def totxtpassword(event):
txtpassword.focus()
def tobtnsave(event):
btnsave.focus()
frmtop = Frame(mainframe)
frmtop.pack()
Label(frmtop, text='用户名:', anchor=E).grid(row=1, column=1)
username = StringVar()
txtusername = Entry(frmtop, textvariable=username)
txtusername.grid(row=1, column=2)
txtusername.bind('', totxtpassword)
txtusername.focus()
Label(frmtop, text='密 码:', anchor=E).grid(row=2, column=1)
password = StringVar()
txtpassword = Entry(frmtop, textvariable=password, show='*')
txtpassword.grid(row=2, column=2)
txtpassword.bind('', tobtnsave)
frmbottom = Frame(mainframe)
frmbottom.pack(pady=5)
btnsave = Button(frmbottom, text='保存')
btnsave.config(width=8, activeforeground='red')
btnsave.grid(row=1, column=1)
btnclear = Button(frmbottom, text='重置', width=8)
btnclear.config(width=8, activeforeground='red')
btnclear.grid(row=1, column=2)
def save():
username = txtusername.get()
password = txtpassword.get()
if username == '':
showerror(systitle, '用户名不能为空!')
else:
if find(username):
showerror(systitle, '用户名已存在,重新输入用户名!')
txtusername.focus()
txtusername.select_range(0, END)
else:
if password == '':
showerror(systitle, '密码不能为空!')
txtpassword.focus()
else:
conn = getconn()
conn.execute('insert into user values(?, ?)', (username, password))
conn.commit()
conn.close()
showinfo(systitle, '成功添加用户[' + username + ']!')
def clear():
username.set('')
password.set('')
txtusername.focus()
btnclear.config(command=clear)
btnsave.config(command=save)
# 查找、修改或删除
def check_update():
global mainframe
mainframe.destroy()
mainframe = LabelFrame(text='查找、修改或删除用户', width=400, height=300)
mainframe.pack(anchor=CENTER, pady=20, ipadx=5, ipady=5)
findframe = LabelFrame(mainframe, text='查找用户')
findframe.pack(anchor=CENTER, padx=10, ipadx=5, ipady=5, fill=X)
Label(findframe, text='输入待查用户名:', anchor=E).grid(row=1, column=1)
username = StringVar()
txtusername = Entry(findframe, textvariable=username)
txtusername.grid(row=1, column=2)
txtusername.focus()
btnfind = Button(findframe, text='查找')
btnfind.grid(row=1, column=3)
deleteframe = LabelFrame(mainframe, text='删除用户')
deleteframe.pack(anchor=CENTER, padx=10, ipadx=5, ipady=5, fill=X)
btndelete = Button(deleteframe, text='删除用户', state=DISABLED)
btndelete.pack(fill=X, padx=10)
editframe = LabelFrame(mainframe, text='修改用户')
editframe.pack(anchor=CENTER, padx=10, ipadx=5, ipady=5, fill=X)
Label(editframe, text='新用户名:').grid(row=1, column=1)
newusername = StringVar()
txtnewusername = Entry(editframe, textvariable=newusername)
txtnewusername.grid(row=1, column=2)
Label(editframe, text='新 密 码:').grid(row=2, column=1)
newpassword = StringVar()
txtnewpassword = Entry(editframe, textvariable=newpassword, show='*')
txtnewpassword.grid(row=2, column=2)
btnupdate = Button(editframe, text='更新用户信息', state=DISABLED)
btnupdate.grid(row=1, column=3, rowspan=2, sticky=N + S)
def finduser():
username = txtusername.get()
if not find(username):
showinfo(systitle, '[%s]还未注册!' % username)
else:
btndelete.config(state=NORMAL)
btnupdate.config(state=NORMAL)
def deleteuser():
username = txtusername.get();
if askyesno(systitle, '要删除用户[%s]吗?' % username):
conn = getconn()
conn.execute('delete from user where username = ?', (username,))
conn.commit()
conn.close()
showinfo(systitle, '成功删除用户[%s]!' % username)
txtusername.delete(0, END)
btndelete.config(state=DISABLED)
btnupdate.config(state=DISABLED)
def updateuser():
username = txtusername.get()
newusername = txtnewusername.get()
if newusername == '':
showerror(systitle, '新用户名不能为空!')
txtnewusername.focus();
else:
if find(newusername):
showerror(systitle, '用户名[%s]已经注过册!' % newusername)
txtnewusername.focus()
else:
newpassword = txtnewpassword.get();
if newpassword == '':
showerror(systitle, '密码不能为空!')
else:
conn = getconn()
conn.execute('update user set username = ?, password = ? where username = ?',
(newusername, newpassword, username))
conn.commit()
conn.close()
showinfo(systitle, '用户数据更新成功!')
btnfind.config(command=finduser)
btndelete.config(command=deleteuser)
btnupdate.config(command=updateuser)
# 退出系统
def exit():
if askokcancel(systitle, '你要退出系统吗?'):
root.destroy()
# 创建菜单系统
menubar = Menu(root)
root.config(menu=menubar)
file = Menu(menubar, tearoff=0)
file.add_command(label='创建/重置用户数据库', command=resetdb)
file.add_separator()
file.add_command(label='显示全部注册用户', command=showall)
file.add_command(label='查找/修改/删除用户', command=check_update)
file.add_command(label='添加新用户', command=adduser)
file.add_separator()
file.add_command(label='退出系统', command=exit)
menubar.add_cascade(label='系统操作', menu=file)
mainloop()
except Exception as ex:
log = open(logfile, 'a')
dt = datetime.today()
# 为用户显示异常日志信息
print('\n程序出错!')
print('日期时间:', dt)
print('异常信息:', ex)
print('\n堆栈跟踪信息:')
print_tb(ex.__traceback__)
# 将日志信息写入文件
print('\n程序出错!', file=log)
print('日期时间:', dt, file=log)
print('异常信息:', ex.args[0], file=log)
print('\n堆栈跟踪信息:', file=log)
print_tb(ex.__traceback__, file=log)
log.close()
showerror(systitle, '发生了错误,系统已退出!')
二、运行效果