这是本人用Python Tkinter做的一个登录程序,因为连接了SQL数据库,所以需要新建一个“账号登录”数据库,创建一张“登录注册”表,然后再编写代码运行。里面有详细的注释说明,对于有一定基础知识的同学来说比较友好。
期间我发现了很多问题所在,控件框架布局基本不变,主要是功能实现方法,反反复复修改了很多次,吸取了很多经验教训。
数据库连接信息,用SQL Server身份验证登录,记住登录名和密码。
新建一个“账号登录”数据库,在里面创建一张“登录注册表”,设置好列名username、password和数据类型。
输入的密码采用了MD5加盐加密操作,所以password一栏显示为密文。
然后就是python窗体源代码了,我这里创建了5个Form窗体,包含了账号登录、账号注册、修改密码、账号注销四个功能。虽然这些功能函数和控件是相关联的,这里我还是拆分解析一下各部分代码功能。
我们首先来连接一下SQL Server数据库,记得要导入相关的安装包
import pymssql# 数据库连接conn = pymssql.connect('服务器名称', '登录名', '密码', '数据库名称', )#例如:conn = pymssql.connect('WSDFERE\SQLEXPRESS', 'sa', '1234567890, '账号登录', )## windows本地身份验证登录:conn = pymssql.connect(server='服务器名称', database='数据库名称')if conn:print("数据库连接成功!")else:print("数据库连接失败!")cur = conn.cursor()#创建一个游标对象,在函数里面调用,在运行过程中不能断开连接,否则会报错。直到关闭窗口时再关闭游标对象和数据库对象连接。
再来创建第1个窗体Form1
# 窗体居中显示def Center(winform):winform.config(background="#C0C0C0")width = winform.winfo_screenwidth()# 获取屏幕宽度height = winform.winfo_screenheight()# 获取屏幕高度winform.resizable(False, False)# 窗体固定尺寸winform.geometry("%dx%d+%d+%d" % (width / 2.0, height / 2.0, width / 4.0, height / 4.0))Form1 = tkinter.Tk()# 创建一个窗体Form1Form1.title('登录界面')#设置窗体标题#调用Center方法实现窗体居中Center(Form1)# 窗体Form1居中显示# protocol是一个创建销毁窗口的方法,绑定Exit()函数以后,在任意一个窗口右上方点击“X”后都能直接退出并关闭所有窗体后台程序Form1.protocol("WM_DELETE_WINDOW", Exit)# 点击右上方的“X”后退出所有窗体程序
以此类推,再创建其他4个窗体
# 窗体居中显示def Center(winform):winform.config(background="#C0C0C0")width = winform.winfo_screenwidth()# 获取屏幕宽度height = winform.winfo_screenheight()# 获取屏幕高度winform.resizable(False, False)# 窗体固定尺寸winform.geometry("%dx%d+%d+%d" % (width / 2.0, height / 2.0, width / 4.0, height / 4.0))# 主程序代码Form1 = tkinter.Tk()# 创建一个窗体Form1Form2 = tkinter.Tk()# 创建一个窗体Form2Form3 = tkinter.Tk()# 创建一个窗体Form3Form4 = tkinter.Tk()# 创建一个窗体Form4Form5 = tkinter.Tk()# 创建一个窗体Form5#设置各窗体标题Form1.title('登录界面')Form2.title("主界面")Form3.title("注册界面")Form4.title("修改密码")Form5.title("账号注销")#调用Center()方法使窗体居中显示Center(Form1)# 窗体Form1居中显示Center(Form2)# 窗体Form2居中显示Center(Form3)# 窗体Form3居中显示Center(Form4)# 窗体Form4居中显示Center(Form5)# 窗体Form5居中显示# 一次性创建5个窗体后,需要用withdraw()来隐藏其他窗口,只显示一个登录窗口Form1Form2.withdraw()# 隐藏窗体Form2Form3.withdraw()# 隐藏窗体Form3Form4.withdraw()# 隐藏窗体Form4Form5.withdraw()# 隐藏窗体Form5# protocol是一个创建销毁窗口的方法,绑定Exit()函数以后,在任意一个窗口右上方点击“X”后都能直接退出并关闭所有窗体后台程序Form1.protocol("WM_DELETE_WINDOW", Exit)# 点击右上方的“X”后退出所有窗体程序Form2.protocol("WM_DELETE_WINDOW", Exit)Form3.protocol("WM_DELETE_WINDOW", Exit)Form4.protocol("WM_DELETE_WINDOW", Exit)Form5.protocol("WM_DELETE_WINDOW", Exit)Form5.mainloop()Form4.mainloop()Form3.mainloop()Form2.mainloop()Form1.mainloop()
窗体Form1(登录界面)的相关控件代码
label1 = Label(Form1, text="账号", bg="#C0C0C0", font=('微软雅黑', 18), bd=5, relief='flat', justify="center", )label1.place(x=200, y=100)#label1控件在Form1上面,文本显示为“账号”,十六进制背景颜色,18号微软雅黑字体,边框宽度为5px,默认样式,文本居中显示。#label1控件位置距离窗体左边框200px,距离上边框100px.label2 = Label(Form1, text="密码", bg="#C0C0C0", font=('微软雅黑', 18), bd=5, relief='flat', justify="center")label2.place(x=200, y=215)text1 = tkinter.Entry(Form1, font=("微软雅黑", 17), relief="flat", width=28, borderwidth=5, justify="center")text1.place(x=350, y=105)#Entry控件text1在Form1上面,17号微软雅黑字体,默认样式,宽度为28px,边框宽度为5px,文本居中显示。#text1控件位置距离窗体左边框350px,距离上边框105px.text2 = tkinter.Entry(Form1, font=("微软雅黑", 17), show="*", relief="flat", width=28, borderwidth=5, justify="center")text2.place(x=350, y=220)text1.focus()# 鼠标光标定位在文本输入框text1上面button1 = Button(Form1, text="登录", relief='flat', font=('黑体', 17), padx=15, pady=5, command=Login, )button1.place(x=330, y=370)#Button控件button1在Form1上面,文本显示为“登录”,默认样式,17号黑体字体,文本与边框的水平距离和垂直距离(即内边距)为15px和5px,调用的函数方法Login():登录功能button2 = Button(Form1, text="重置", relief='flat', font=('黑体', 17), padx=15, pady=5, command=Clear1, )button2.place(x=750, y=370)#调用的函数为Clear1():重置Form1输入信息button3 = Button(Form1, text="注册", relief='flat', font=('黑体', 17), padx=15, pady=5, command=lambda: Form(3), )button3.place(x=330, y=500)#调用带参数的函数Form(*args):跳转注册界面button4 = Button(Form1, text="退出", relief='flat', font=('黑体', 17), padx=15, pady=5, command=Exit)button4.place(x=750, y=500)#调用的函数为Exit():退出所有窗体程序和进程
窗体Form3(注册界面)相关的控件代码
label11 = Label(Form3, text="注册账号", bg="#C0C0C0", font=('微软雅黑', 18), bd=5, relief='flat', justify="center")label11.place(x=140, y=100)#Label控件label11在Form3上面,文本显示为“注册账号”,十六进制背景颜色,18号微软雅黑字体,边框宽度为5px,默认样式,文本居中显示。#label11的位置距离窗体左边框140px,距离上边框100px。label12 = Label(Form3, text="输入密码", bg="#C0C0C0", font=('微软雅黑', 18), bd=5, relief='flat', justify="center")label12.place(x=140, y=200)label13 = Label(Form3, text="确认密码", bg="#C0C0C0", font=('微软雅黑', 18), bd=5, relief='flat', justify="center")label13.place(x=140, y=300)text11 = tkinter.Entry(Form3, font=("微软雅黑", 17), relief="flat", borderwidth=5, width=28, justify="center")text11.place(x=380, y=105)text12 = tkinter.Entry(Form3, font=("微软雅黑", 17), relief="flat", show="*", borderwidth=5, width=28, justify="center")text12.place(x=380, y=205)text13 = tkinter.Entry(Form3, font=("微软雅黑", 17), relief="flat", show='*', borderwidth=5, width=28, justify="center")text13.place(x=380, y=305)button11 = Button(Form3, text="确定", relief='groove', font=('黑体', 17), padx=15, pady=5, command=Register)button11.place(x=250, y=450)#button11调用了Register()函数:注册功能。button12 = Button(Form3, text="重置", relief='groove', font=('黑体', 17), padx=15, pady=5, command=Clear3)button12.place(x=550, y=450)#button12调用了Clear3()方法,重置Form3界面输入的信息。button13 = Button(Form3, text="取消", relief='groove', font=('黑体', 17), padx=15, pady=5, command=lambda: Form(1))button13.place(x=850, y=450)#button13调用了带参数的函数方法Form(3):跳转登录界面Form1。
窗体Form2(主界面)的相关控件代码
button21 = Button(Form2, text="退出", relief='flat', font=('黑体', 17), padx=15, pady=5, command=Exit)button21.place(x=750, y=600)button22 = Button(Form2, text="修改密码", relief="flat", font=("黑体", 17), padx=15, pady=5, command=lambda: Form(4))button22.place(x=250, y=450)button23 = Button(Form2, text="账号注销", relief="flat", font=("黑体", 17), padx=15, pady=5, command=lambda: Form(5), )button23.place(x=680, y=450)button24 = Button(Form2, text="返回", relief="flat", font=("黑体", 17), padx=15, pady=5, command=reForm1, )button24.place(x=320, y=600)label21 = tkinter.Label(Form2, text="账号:", font=("微软雅黑", 18), padx=10, pady=10, bg="#C0C0C0", relief="flat", justify="center", )label21.place(x=100, y=60)label22 = tkinter.Label(Form2, text=text1.get(), font=("微软雅黑", 18), padx=10, pady=10, bg="#C0C0C0", relief="flat", justify="left", )label22.place(x=250, y=60)
** 窗体Form4(修改密码)界面相关的窗体代码**
label32 = Label(Form4, text="旧密码", bg="#C0C0C0", font=('微软雅黑', 18), bd=5, relief='flat', justify="center")label32.place(x=180, y=200)label33 = Label(Form4, text="新密码", bg="#C0C0C0", font=('微软雅黑', 18), bd=5, relief='flat', justify="center")label33.place(x=180, y=300)text32 = tkinter.Entry(Form4, font=("微软雅黑", 17), relief="flat", borderwidth=5, width=28, justify="center")text32.place(x=380, y=205)text33 = tkinter.Entry(Form4, font=("微软雅黑", 17), show='*', relief="flat", borderwidth=5, width=28, justify="center")text33.place(x=380, y=305)button31 = Button(Form4, text="确定", relief='groove', font=('黑体', 17), padx=15, pady=5, command=Change)button31.place(x=250, y=450)button32 = Button(Form4, text="重置", relief='groove', font=('黑体', 17), padx=15, pady=5, command=Clear4)button32.place(x=550, y=450)button33 = Button(Form4, text="取消", relief='groove', font=('黑体', 17), padx=15, pady=5, command=lambda: Form(2))button33.place(x=850, y=450)
窗体Form5(账号注销)界面的相关控件代码
label41 = Label(Form5, text="账号密码", bg="#C0C0C0", font=('微软雅黑', 18), bd=5, relief='flat', justify="center")label41.place(x=120, y=205)text41 = tkinter.Entry(Form5, font=("微软雅黑", 17), relief="flat", borderwidth=5, width=28, justify="center")text41.place(x=350, y=205)button41 = Button(Form5, text="注销", relief='groove', font=('黑体', 17), padx=15, pady=5, command=Cancel, )button41.place(x=280, y=350)button42 = Button(Form5, text="重置", relief='groove', font=('黑体', 17), padx=15, pady=5, command=Clear5, )button42.place(x=565, y=350)button43 = Button(Form5, text="取消", relief='groove', font=('黑体', 17), padx=15, pady=5, command=lambda: Form(2), )button43.place(x=850, y=350)
MD5加盐加密方法:
# MD5加盐加密操作def Encrypt(SaltPwd):obj = hashlib.md5(SaltPwd.encode("utf-8"))obj.update(SaltPwd.encode("utf-8"))return obj.hexdigest()
然后是相关的函数功能实现,账号登录功能方法:Login()
def Login():user = text1.get().strip()# 输入的账号pwd = text2.get().strip()# 输入的密码CipherText = Encrypt(user + pwd)# 对账号和密码进行MD5加盐加密操作后的密文,用来验证账号密码是否正确,注册的时候密码pwd也是以密文形式存储的sql = 'select count(*) from 登录注册表 where username=%s 'cur.execute(sql, (user,))# 通过筛选输入的账号来判断账号是否存在,result = cur.fetchone()if user == "":tkinter.messagebox.showinfo("提示", "用户名不得为空!")text1.focus()elif pwd == "":tkinter.messagebox.showinfo("提示", "密码不得为空!")text2.focus()elif result[0] == True:# 如果读取到了一条返回值,则说明账号存在;然后再判断密码是否正确sql2 = 'select password from 登录注册表 where username=%s 'cur.execute(sql2, (user,))# 通过SQL语句筛选‘输入账号user’的密码返回值result2 = cur.fetchone()# 获取返回的密码(返回一条记录)if result2[0] == CipherText:# 如果密文等于返回值密码,则登录成功tkinter.messagebox.showinfo("提示", "登录成功!")label22["text"] = user# 登录成功后,输入账号user的值会显示在住界面Form2的label22上面Clear1()Form(2)# 跳转主界面Form2else:tkinter.messagebox.showinfo("提示", "密码错误!")text2.delete(0, tkinter.END)else:# 没有读取到返回值记录messbox = tkinter.messagebox.askyesno("提示", "账号不存在,是否选择注册一个新账号" />)if messbox == YES:Clear1()Form(3)else:Clear1()text1.focus()
账号注册功能方法:Register()
# 界面Form3:注册功能def Register():newuser = text11.get().strip()# 注册账号newpwd = text12.get().strip()# 注册账号密码renewpwd = text13.get().strip()# 确认账号密码CipherText = Encrypt(newuser + newpwd)# 对账号和密码进行加盐加密后的密文sql = 'select count(*) from 登录注册表 where username=%s'cur.execute(sql, (newuser,))result = cur.fetchone()# 获取返回值(返回一条记录)if newuser == "":tkinter.messagebox.showinfo("提示", "注册账号不得为空!")text11.focus()elif newpwd == "":tkinter.messagebox.showinfo("提示", "注册账号密码不得为空!")text12.focus()elif newpwd != renewpwd:tkinter.messagebox.showinfo("提示", "两次密码不一致,请重新输入密码!")text13.delete(0, tkinter.END)text13.focus()elif result[0] == True:#获取到一条返回值,则说明账号已存在tkinter.messagebox.askyesno("提示", "该账号已注册!请重新注册!")Clear3()else:tkinter.messagebox.showinfo("提示", "新账号注册成功!")Clear3()sql2 = "insert into 登录注册表 (username, password) values (%s, %s)"cur.execute(sql2, (newuser, CipherText,))# 将游标对象cur关联sql2语句,保存注册后的账号信息(密码以密文的形式保存),登录功能也是通过密文来判断账号密码是否正确conn.commit()# 提交sql2语句到SQL数据库,并执行该语句,查询语句不需要commit()Form(1)# 返回登录界面Form1
修改密码功能函数:Change()
# 界面4:修改账号密码def Change():user = label22["text"]# 窗体Form2显示的账号oldpwd = text32.get().strip()# 旧密码newpwd = text33.get().strip()# 新密码CipherText1 = Encrypt(user + oldpwd)# 对账号和旧密码进行加盐加密后的密文,用来验证账号密码是否正确CipherText2 = Encrypt(user + newpwd)# 对账号和新密码进行加盐加密后的密文,验证密码成功后将替换旧密码sql = 'select password from 登录注册表 where username=%s 'cur.execute(sql, (user,))# 通过user来获取返回的密码(密文形式)result = cur.fetchone()# 获取返回值(返回一条记录)if oldpwd == "":tkinter.messagebox.showinfo("提示", "密码不得为空!")text32.focus()elif newpwd == "":tkinter.messagebox.showinfo("提示", "请输入新密码!")text33.focus()elif result[0] == CipherText1:tkinter.messagebox.showinfo("提示", "账号密码修改成功!!")sql2 = 'update 登录注册表 set password=%s where username=%s'cur.execute(sql2, (CipherText2, user,))# 将游标对象cur关联sql2语句,保存修改后的账号密码(以密文的形式保存)conn.commit()# 提交sql2语句到SQL数据库,并执行该语句,查询语句不需要使用commit()Clear4()Form(1)# 跳转主界面Form1,重新登录else:tkinter.messagebox.showinfo("提示", "账号密码错误!")Clear4()
账号注销功能函数:Cancel()
# 界面Form5:账号注销def Cancel():user = label22["text"]# 这里的账号是登录成功后,主界面窗体Form2显示的账号pwd = text41.get().strip()CipherText = Encrypt(user + pwd)# 对账号和密码进行加盐加密后的密文sql = 'select password from 登录注册表 where username=%s 'cur.execute(sql, (user,))result = cur.fetchone()# 获取密码返回值(返回一条记录)if text41.get() == "":tkinter.messagebox.showinfo("提示", "密码不得为空!")text41.focus()elif result[0] == CipherText:tkinter.messagebox.showinfo("提示", "账号注销成功!")sql2 = 'delete from 登录注册表 where username=%s 'cur.execute(sql2, (user,))# 从SQL数据库中删除注销后的账号信息conn.commit()# 提交sql2语句到SQL数据库,并执行该语句,查询语句不需要使用commit()Clear5()Form(1)# 跳转登录界面Form1else:tkinter.messagebox.showinfo("提示", "账号密码错误!")Clear5()
重置窗体输入信息的方法函数:Clear()
# 登录界面Form1输入信息重置def Clear1(*args):text1.delete(0, tkinter.END)text2.delete(0, tkinter.END)text1.focus()# 鼠标光标定位在文本输入框text1上# 注册界面Form3输入信息重置def Clear3(*args):text11.delete(0, tkinter.END)text12.delete(0, tkinter.END)text13.delete(0, tkinter.END)text11.focus()# 鼠标光标定位在文本输入框text11上# 修改界面Form4输入信息重置def Clear4(*args):text32.delete(0, tkinter.END)text33.delete(0, tkinter.END)text32.focus()##鼠标光标定位在文本输入框text31上# 注销界面Form5输入信息重置def Clear5():text41.delete(0, tkinter.END)text41.focus()##鼠标光标定位在文本输入框text41上
*跳转窗体界面的方法函数:Form(args)
# 跳转指定界面窗体def Form(st):if st == 1:# 在跳转的窗体的时候要用withdraw()来隐藏当前窗体,不能使用destroy()来关闭窗体,因为会断掉与其他窗体的数据关联,特别是在连接了数据库的情况下。Form2.withdraw()# 隐藏窗体Form2Form3.withdraw()# 隐藏窗体Form2Form4.withdraw()# 隐藏窗体Form2Form5.withdraw()# 隐藏窗体Form2Center(Form1)# 窗体Form1居中显示Form1.deiconify()# 窗体Form1显示text1.focus()# 鼠标光标定位在文本输入框text1elif st == 2:Form1.withdraw()Form3.withdraw()Form4.withdraw()Form5.withdraw()Center(Form2)Form2.deiconify()elif st == 3:Form1.withdraw()Form2.withdraw()Form4.withdraw()Form5.withdraw()Center(Form3)Form3.deiconify()text11.focus()elif st == 4:Form1.withdraw()Form2.withdraw()Form3.withdraw()Form5.withdraw()Center(Form4)Form4.deiconify()text32.focus()elif st == 5:Form1.withdraw()Form2.withdraw()Form3.withdraw()Form4.withdraw()Center(Form5)Form5.deiconify()text41.focus()def reForm1():messbox = tkinter.messagebox.askyesno("提示", "是否返回登录界面?")if messbox == YES:Form(1)
最后,就是完整的窗体程序源代码,我将其封装在一个类里面。其中,控件的位置用的是相对位置表示,目的是为了适应不同设备的分辨率。
import hashlibimport sysimport tkinterimport tkinter.messageboxfrom tkinter import *import pymssqlclass Account:# 数据库连接def __init__(self):self.__conn = pymssql.connect(server='ASEKJHFDWEK', database='账号登录')# windows本地身份验证登录#账号密码验证 self.__conn = pymssql.connect('服务器名称', '账号', '密码', '数据库名称', )if self.__conn:print("数据库连接成功!")else:print("数据库连接失败!")# 登录界面self.__Form1输入信息重置def __Clear1(self):self.__text1.delete(0, tkinter.END)self.__text2.delete(0, tkinter.END)self.__text1.focus()# 鼠标光标定位在文本输入框self.__text1上# 注册界面self.__Form3输入信息重置def __Clear3(self):self.__text11.delete(0, tkinter.END)self.__text12.delete(0, tkinter.END)self.__text13.delete(0, tkinter.END)self.__text11.focus()# 鼠标光标定位在文本输入框self.__text11上# 修改界面self.__Form4输入信息重置def __Clear4(self):self.__text32.delete(0, tkinter.END)self.__text33.delete(0, tkinter.END)self.__text32.focus()##鼠标光标定位在文本输入框self.__text31上# 注销界面self.__Form5输入信息重置def __Clear5(self):self.__text41.delete(0, tkinter.END)self.__text41.focus()##鼠标光标定位在文本输入框self.__text41上# 退出所有窗体程序运行def __Exit(self):self.__conn.close()# 关闭数据库连接对象self.__Form1.quit()self.__Form1.destroy()# 关闭窗体·self.__Form1后台运行self.__Form2.quit()self.__Form2.destroy()self.__Form3.quit()self.__Form3.destroy()self.__Form4.quit()self.__Form4.destroy()self.__Form5.quit()self.__Form5.destroy()sys.exit(0)# 窗体居中显示def __Center(self, winform):winform.config(background="#CFCFCF")self.__width = winform.winfo_screenwidth()# 获取屏幕宽度self.__height = winform.winfo_screenheight()# 获取屏幕高度# winform.resizable(False, False)# 窗体固定尺寸winform.geometry("%dx%d+%d+%d" % (self.__width / 2.0, self.__height / 2.0, self.__width / 4.0, self.__height / 4.0))# protocol是一个创建销毁窗口的方法,绑定Exit()函数以后,在任意一个窗口右上方点击“X”后都能直接退出并关闭所有窗体后台程序winform.protocol("WM_DELETE_WINDOW", self.__Exit)# 点击右上方的“X”后退出所有窗体程序# 跳转指定界面窗体def __Form(self, st):if st == 1:# 在跳转的窗体的时候要用withdraw()来隐藏当前窗体,不能使用destroy()来关闭窗体,# 因为会断掉与其他窗体的数据关联,特别是在连接了数据库的情况下。self.__Form2.withdraw()# 隐藏窗体self.__Form2self.__Form3.withdraw()# 隐藏窗体self.__Form2self.__Form4.withdraw()# 隐藏窗体self.__Form2self.__Form5.withdraw()# 隐藏窗体self.__Form2self.__Center(self.__Form1)# 窗体self.__Form1居中显示self.__Form1.deiconify()# 窗体self.__Form1显示self.__text1.focus()# 鼠标光标定位在文本输入框self.__text1elif st == 2:self.__Form1.withdraw()self.__Form3.withdraw()self.__Form4.withdraw()self.__Form5.withdraw()self.__Center(self.__Form2)self.__Form2.deiconify()elif st == 3:self.__Form1.withdraw()self.__Form2.withdraw()self.__Form4.withdraw()self.__Form5.withdraw()self.__Center(self.__Form3)self.__Form3.deiconify()self.__text11.focus()elif st == 4:self.__Form1.withdraw()self.__Form2.withdraw()self.__Form3.withdraw()self.__Form5.withdraw()self.__Center(self.__Form4)self.__Form4.deiconify()self.__text32.focus()elif st == 5:self.__Form1.withdraw()self.__Form2.withdraw()self.__Form3.withdraw()self.__Form4.withdraw()self.__Center(self.__Form5)self.__Form5.deiconify()self.__text41.focus()def __reForm1(self):# 返回登录界面self.__Form1self.__messbox = tkinter.messagebox.askyesno("提示", "是否返回登录界面?")if self.__messbox == YES:self.__Form(1)# MD5加盐加密操作def __Encrypt(self, SaltPwd):self.__obj = hashlib.md5(SaltPwd.encode("gbk"))self.__obj.update(SaltPwd.encode("utf-8"))return self.__obj.hexdigest()# 账号登录操作def __Login(self):self.__cur = self.__conn.cursor()self.__user = self.__text1.get().strip()# 输入的账号self.__pwd = self.__text2.get().strip()# 输入的密码self.__CipherText = self.__Encrypt(self.__user + self.__pwd)# 对账号和密码进行MD5加盐加密操作后的密文,用来验证账号密码是否正确,注册的时候密码pwd也是以密文形式存储的self.__sql = 'select count(*) from 登录注册表 where username=%s 'self.__cur.execute(self.__sql, (self.__user,))# 通过筛选输入的账号来判断账号是否存在self.__result = self.__cur.fetchone()if self.__user == "":tkinter.messagebox.showinfo("提示", "用户名不得为空!")self.__text1.focus()elif self.__pwd == "":tkinter.messagebox.showinfo("提示", "密码不得为空!")self.__text2.focus()elif self.__result[0] == FALSE:# 如果读取到了一条返回值,则说明账号存在;然后再判断密码是否正确messbox = tkinter.messagebox.askyesno("提示", "账号不存在,是否选择注册一个新账号?")if messbox == YES:self.__Clear1()self.__Form(3)else:self.__Clear1()self.__text1.focus()else:self.__VerifyLogin(self.__user)# 验证账号密码是否正确def __VerifyLogin(self, user):self.__cur = self.__conn.cursor()self.__sql2 = 'select count(*) from 登录注册表 where username=%s 'self.__cur.execute(self.__sql2, (user,))# 通过SQL语句筛选‘输入账号user’的密码返回值self.__result2 = self.__cur.fetchone()# 获取返回的密码(返回一条记录)if self.__result2[0] == TRUE:# 如果密文等于返回值密码,则登录成功tkinter.messagebox.showinfo("提示", "登录成功!")self.__label22["text"] = user# 登录成功后,输入账号user的值会显示在住界面self.__Form2的self.__label22上面self.__Clear1()self.__Form(2)# 跳转主界面self.__Form2else:tkinter.messagebox.showinfo("提示", "账号密码错误!")self.__text2.delete(0, tkinter.END)# 界面self.__Form3:注册功能def __Register(self):# 创建一个游标对象curself.__cur = self.__conn.cursor()self.__user = self.__text11.get().strip()# 注册账号self.__newpwd = self.__text12.get().strip()# 注册账号密码self.__renewpwd = self.__text13.get().strip()# 确认账号密码self.__CipherText = self.__Encrypt(self.__user + self.__newpwd)# 对账号和密码进行加盐加密后的密文sql = 'select count(*) from 登录注册表 where username=%s'self.__cur.execute(sql, (self.__user,))self.__result = self.__cur.fetchone()# 获取返回值(返回一条记录)if self.__user == "":tkinter.messagebox.showinfo("提示", "注册账号不得为空!")self.__text11.focus()elif self.__newpwd == "":tkinter.messagebox.showinfo("提示", "注册账号密码不得为空!")self.__text12.focus()elif self.__newpwd != self.__renewpwd:tkinter.messagebox.showinfo("提示", "两次密码不一致,请重新输入密码!")self.__text13.delete(0, tkinter.END)self.__text13.focus()elif self.__result[0] == True:tkinter.messagebox.askyesno("提示", "该账号已注册!请重新注册!")self.__Clear3()else:self.__SaveRegister(self.__user, self.__CipherText)# 保存注册后的账号密码消息到数据库def __SaveRegister(self, user, CipherText):try:self.__cur = self.__conn.cursor()tkinter.messagebox.showinfo("提示", "新账号注册成功!")sql2 = "insert into 登录注册表 (username, password) values (%s, %s)"self.__cur.execute(sql2, (self.__user, self.__CipherText,))# 将游标对象cur关联sql2语句,保存注册后的账号信息(密码以密文的形式保存)self.__conn.commit()# 提交sql2语句到SQL数据库,并执行该语句,查询语句不需要commit()self.__Clear3()self.__Form(1)# 返回登录界面self.__Form1except EXCEPTION as ex:tkinter.messagebox.showinfo("提示", "账号注册失败!")tkinter.messagebox.showinfo("提示", ex)self.__Clear3()self.__text11.focus()# 界面4:修改账号密码def __Change(self):self.__cur = self.__conn.cursor()self.__user = self.__label22["text"]# 账号self.__oldpwd = self.__text32.get().strip()# 旧密码self.__newpwd = self.__text33.get().strip()# 新密码self.__CipherText1 = self.__Encrypt(self.__user + self.__oldpwd)# 对账号和旧密码进行加盐加密后的密文self.__CipherText2 = self.__Encrypt(self.__user + self.__newpwd)# 对账号和新密码进行加盐加密后的密文self.__sql = 'select count(*) from 登录注册表 where username=%s 'self.__cur.execute(self.__sql, (self.__user,))# 将游标对象cur关联sql语句,判断账号和密码是否正确self.__result = self.__cur.fetchone()# 获取返回值(返回一条记录)if self.__oldpwd == "":tkinter.messagebox.showinfo("提示", "密码不得为空!")self.__text32.focus()elif self.__newpwd == "":tkinter.messagebox.showinfo("提示", "请输入新密码!")self.__text33.focus()elif self.__result[0] == TRUE:self.__SaveChange(self.__user, self.__CipherText)else:tkinter.messagebox.showinfo("提示", "账号密码错误!")self.__Clear4()self.__text32.focus()# 保存修改后的账号密码信息def __SaveChange(self, user, CipherText):try:self.__cur = self.__conn.cursor()self.__sql2 = 'update 登录注册表 set password=%s where username=%s'self.__cur.execute(self.__sql2, (self.__CipherText, self.__user,))# 将游标对象cur关联sql2语句,保存修改后的账号密码(以密文的形式保存)self.__conn.commit()# 提交sql2语句到SQL数据库,并执行该语句,查询语句不需要使用commit()tkinter.messagebox.showinfo("提示", "账号密码修改成功!!")self.__Clear4()self.__Form(1)# 跳转主界面self.__Form1,重新登录except EXCEPTION as ex:tkinter.messagebox.showinfo("提示", "账号密码修改失败!")tkinter.messagebox.showinfo("提示", ex)self.__text32.focus()# 界面self.__Form5:账号注销def __Cancel(self):self.__cur = self.__conn.cursor()self.__user = self.__label22["text"]# 这里的账号是登录成功后,主界面窗体self.__Form2显示的账号self.__pwd = self.__text41.get().strip()self.__CipherText3 = self.__Encrypt(self.__user + self.__pwd)# 对账号和密码进行加盐加密后的密文self.__sql = 'select password from 登录注册表 where username=%s'self.__cur.execute(self.__sql, (self.__user,))# 将游标对象cur关联sql语句,通过user+密文来判断账号密码是否输入正确self.__result3 = self.__cur.fetchone()# 获取返回值(返回一条记录)if self.__text41.get().strip() == "":tkinter.messagebox.showinfo("提示", "密码不得为空!")self.__text41.focus()elif self.__result3[0] == self.__CipherText3:self.__DeleteCancel(self.__user)else:tkinter.messagebox.showinfo("提示", "账号密码错误!")self.__Clear5()self.__text41.focus()# 从QL数据库删除注销后的账号信息def __DeleteCancel(self, user):try:self.__cur = self.__conn.cursor()self.__sql2 = 'delete from 登录注册表 where username=%s 'self.__cur.execute(self.__sql2, (user,))# 将游标对象cur关联sql2语句,从SQL数据库中删除注销后的账号信息self.__conn.commit()# 提交sql2语句到SQL数据库,并执行该语句,查询语句不需要使用commit()tkinter.messagebox.showinfo("提示", "账号注销成功!")self.__Clear5()self.__Form(1)# 跳转登录界面self.__Form1except EXCEPTION as ex:tkinter.messagebox.showinfo("提示", "账号注销失败!")tkinter.messagebox.showinfo("提示", ex)self.__Clear5()def Main(self):self.__Form1 = tkinter.Tk()# 创建一个窗体Form1self.__Form2 = tkinter.Tk()# 创建一个窗体Form2self.__Form3 = tkinter.Tk()# 创建一个窗体Form3self.__Form4 = tkinter.Tk()# 创建一个窗体Form4self.__Form5 = tkinter.Tk()# 创建一个窗体Form5self.__Form1.title('登录界面')self.__Form2.title("主界面")self.__Form3.title("注册界面")self.__Form4.title("修改密码")self.__Form5.title("账号注销")self.__Center(self.__Form1)# 窗体Form1居中显示self.__Center(self.__Form2)# 窗体Form2居中显示self.__Center(self.__Form3)# 窗体Form3居中显示self.__Center(self.__Form4)# 窗体Form4居中显示self.__Center(self.__Form5)# 窗体Form5居中显示# 一次性创建5个窗体后,需要用withdraw()来隐藏其他窗口,只显示一个登录窗口Form1self.__Form2.withdraw()# 隐藏窗体Form2self.__Form3.withdraw()# 隐藏窗体Form3self.__Form4.withdraw()# 隐藏窗体Form4self.__Form5.withdraw()# 隐藏窗体Form5# 登录界面Form1代码控件self.__label1 = tkinter.Label(self.__Form1, text="账号", bg="#CFCFCF", font=('微软雅黑', 18), bd=5, relief='flat', justify="center", )self.__label1.place(x=self.__width / 13, y=self.__height / 16)self.__label2 = tkinter.Label(self.__Form1, text="密码", bg="#CFCFCF", font=('微软雅黑', 18), bd=5, relief='flat', justify="center")self.__label2.place(x=self.__width / 13, y=self.__height / 7.4)self.__text1 = tkinter.Entry(self.__Form1, font=("微软雅黑", 17), relief="flat", width=int(self.__width / 90), borderwidth=5, justify="center")self.__text1.place(x=self.__width / 7.5, y=self.__height / 16)self.__text2 = tkinter.Entry(self.__Form1, font=("微软雅黑", 17), show="*", relief="flat", width=int(self.__width / 90), borderwidth=5, justify="center")self.__text2.place(x=self.__width / 7.5, y=self.__height / 7.4)self.__text1.focus()# 鼠标光标定位在文本输入框text1上面self.__button1 = tkinter.Button(self.__Form1, text="登录", bg="#CFCFCF", activebackground="#ffffff", relief='solid', font=('黑体', 17), padx=15, pady=5, command=self.__Login, )self.__button1.place(x=self.__width / 7.5, y=self.__height / 4.3)self.__button2 = tkinter.Button(self.__Form1, text="重置", bg="#CFCFCF", activebackground="#ffffff", relief='solid', font=('黑体', 17), padx=15, pady=5, command=self.__Clear1, )self.__button2.place(x=self.__width / 3.5, y=self.__height / 4.3)self.__button3 = tkinter.Button(self.__Form1, text="注册", bg="#CFCFCF", activebackground="#ffffff", relief='solid', font=('黑体', 17), padx=15, pady=5, command=lambda: self.__Form(3), )self.__button3.place(x=self.__width / 7.5, y=self.__height / 3)self.__button4 = tkinter.Button(self.__Form1, text="退出", bg="#CFCFCF", activebackground="#ffffff", relief='solid', font=('黑体', 17), padx=15, pady=5, command=self.__Exit)self.__button4.place(x=self.__width / 3.5, y=self.__height / 3)# 注册界面Form3代码控件self.__label11 = tkinter.Label(self.__Form3, text="注册账号", bg="#CFCFCF", font=('微软雅黑', 18), bd=5, relief='flat', justify="center")self.__label11.place(x=self.__width / 18, y=self.__height / 16)self.__label12 = tkinter.Label(self.__Form3, text="输入密码", bg="#CFCFCF", font=('微软雅黑', 18), bd=5, relief='flat', justify="center")self.__label12.place(x=self.__width / 18, y=self.__height / 8)self.__label13 = tkinter.Label(self.__Form3, text="确认密码", bg="#CFCFCF", font=('微软雅黑', 18), bd=5, relief='flat', justify="center")self.__label13.place(x=self.__width / 18, y=self.__height / 5.3)self.__text11 = tkinter.Entry(self.__Form3, font=("微软雅黑", 17), relief="flat", borderwidth=5, width=int(self.__width / 90), justify="center")self.__text11.place(x=self.__width / 6.7, y=self.__height / 15.5)self.__text12 = tkinter.Entry(self.__Form3, font=("微软雅黑", 17), relief="flat", show="*", borderwidth=5, width=int(self.__width / 90), justify="center")self.__text12.place(x=self.__width / 6.7, y=self.__height / 7.7)self.__text13 = tkinter.Entry(self.__Form3, font=("微软雅黑", 17), relief="flat", show='*', borderwidth=5, width=int(self.__width / 90), justify="center")self.__text13.place(x=self.__width / 6.7, y=self.__height / 5.2)self.__button11 = tkinter.Button(self.__Form3, text="确定", bg="#CFCFCF", activebackground="#ffffff", relief='solid', font=('黑体', 17), padx=15, pady=5, command=self.__Register)self.__button11.place(x=self.__width / 10, y=self.__height / 3.5)self.__button12 = tkinter.Button(self.__Form3, text="重置", bg="#CFCFCF", activebackground="#ffffff", relief='solid', font=('黑体', 17), padx=15, pady=5, command=self.__Clear3)self.__button12.place(x=self.__width / 4.6, y=self.__height / 3.5)self.__button13 = tkinter.Button(self.__Form3, text="取消", bg="#CFCFCF", activebackground="#ffffff", relief='solid', font=('黑体', 17), padx=15, pady=5, command=lambda: self.__Form(1))self.__button13.place(x=self.__width / 3, y=self.__height / 3.5)# 主界面Form2代码控件self.__button21 = tkinter.Button(self.__Form2, text="退出", bg="#CFCFCF", activebackground="#ffffff", relief='solid', font=('黑体', 17), padx=15, pady=5, command=self.__Exit)self.__button21.place(x=self.__width / 3.5, y=self.__height / 2.7)self.__button22 = tkinter.Button(self.__Form2, text="修改密码", bg="#CFCFCF", activebackground="#ffffff", relief='solid', font=("黑体", 17), padx=15, pady=5, command=lambda: self.__Form(4))self.__button22.place(x=self.__width / 10, y=self.__height / 3.8)self.__button23 = tkinter.Button(self.__Form2, text="账号注销", bg="#CFCFCF", activebackground="#ffffff", relief='solid', font=("黑体", 17), padx=15, pady=5, command=lambda: self.__Form(5), )self.__button23.place(x=self.__width / 3.7, y=self.__height / 3.8)self.__button24 = tkinter.Button(self.__Form2, text="返回", bg="#CFCFCF", activebackground="#ffffff", relief='solid', font=("黑体", 17), padx=15, pady=5, command=self.__reForm1, )self.__button24.place(x=self.__width / 8.8, y=self.__height / 2.7)self.__label21 = tkinter.Label(self.__Form2, text="账号:", font=("微软雅黑", 18), padx=10, pady=10, bg="#CFCFCF", relief="flat", justify="center", )self.__label21.place(x=self.__width / 22, y=self.__height / 18)self.__label22 = tkinter.Label(self.__Form2, text=self.__text1.get(), font=("微软雅黑", 18), padx=10, pady=10, bg="#CFCFCF", relief="flat", justify="left", )self.__label22.place(x=self.__width / 10, y=self.__height / 18)# 修改密码界面Form4代码控件self.__label32 = tkinter.Label(self.__Form4, text="旧密码", bg="#CFCFCF", font=('微软雅黑', 18), bd=5, relief='flat', justify="center")self.__label32.place(x=self.__width / 16, y=self.__height / 12)self.__label33 = tkinter.Label(self.__Form4, text="新密码", bg="#CFCFCF", font=('微软雅黑', 18), bd=5, relief='flat', justify="center")self.__label33.place(x=self.__width / 16, y=self.__height / 7)self.__text32 = tkinter.Entry(self.__Form4, font=("微软雅黑", 17), relief="flat", borderwidth=5, width=int(self.__width / 90), justify="center")self.__text32.place(x=self.__width / 7, y=self.__height / 11.5)self.__text33 = tkinter.Entry(self.__Form4, font=("微软雅黑", 17), show='*', relief="flat", borderwidth=5, width=int(self.__width / 90), justify="center")self.__text33.place(x=self.__width / 7, y=self.__height / 6.8)self.__button31 = tkinter.Button(self.__Form4, text="确定", bg="#CFCFCF", activebackground="#ffffff", relief='solid', font=('黑体', 17), padx=15, pady=5, command=self.__Change)self.__button31.place(x=self.__width / 9.5, y=self.__height / 3.8)self.__button32 = tkinter.Button(self.__Form4, text="重置", bg="#CFCFCF", activebackground="#ffffff", relief='solid', font=('黑体', 17), padx=15, pady=5, command=self.__Clear4)self.__button32.place(x=self.__width / 4.5, y=self.__height / 3.8)self.__button33 = tkinter.Button(self.__Form4, text="取消", bg="#CFCFCF", activebackground="#ffffff", relief='solid', font=('黑体', 17), padx=15, pady=5, command=lambda: self.__Form(2))self.__button33.place(x=self.__width / 3, y=self.__height / 3.8)# 账号注销界面Form5代码控件self.__label41 = tkinter.Label(self.__Form5, text="账号密码", bg="#CFCFCF", font=('微软雅黑', 18), bd=5, relief='flat', justify="center")self.__label41.place(x=self.__width / 18, y=self.__height / 10)self.__text41 = tkinter.Entry(self.__Form5, font=("微软雅黑", 17), relief="flat", borderwidth=5, width=int(self.__width / 95), justify="center")self.__text41.place(x=self.__width / 6.8, y=self.__height / 9.6)self.__button41 = tkinter.Button(self.__Form5, text="注销", bg="#CFCFCF", activebackground="#ffffff", relief='solid', font=('黑体', 17), padx=15, pady=5, command=self.__Cancel, )self.__button41.place(x=self.__width / 10, y=self.__height / 4.5)self.__button42 = tkinter.Button(self.__Form5, text="重置", bg="#CFCFCF", activebackground="#ffffff", relief='solid', font=('黑体', 17), padx=15, pady=5, command=self.__Clear5, )self.__button42.place(x=self.__width / 4.7, y=self.__height / 4.5)self.__button43 = tkinter.Button(self.__Form5, text="取消", bg="#CFCFCF", activebackground="#ffffff", relief='solid', font=('黑体', 17), padx=15, pady=5, command=lambda: self.__Form(2), )self.__button43.place(x=self.__width / 3, y=self.__height / 4.5)self.__Form5.mainloop()self.__Form4.mainloop()self.__Form3.mainloop()self.__Form2.mainloop()self.__Form1.mainloop()if __name__ == '__main__':st = Account()st.Main()
以上就是这个登录程序的全部源代码以及相关说明,仅供学习和参考,感兴趣的小伙伴可以来看看。因为是第一次写的代码程序,还有一些不足之处,有些冗长的部分可以简化,虽然代码比较长,但是原理步骤都差不多,也欢迎大家批评指正。这里我还做了一个不需要连接数据库的窗体登录程序:Python Tkinter窗体程序通过列表和字典来实现账号登录、注册、修改、注销等功能。