我是靠谱客的博主 满意草莓,最近开发中收集的这篇文章主要介绍Python Tkinter窗体程序连接SQL Server数据库实现账号登录、注册、修改、注销等功能(不定时更新),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

这是本人用Python Tkinter做的一个登录程序,因为连接了SQL数据库,所以需要新建一个“账号登录”数据库,创建一张“登录注册”表,然后再编写代码运行。里面有详细的注释说明,对于有一定基础知识的同学来说比较友好。
期间我发现了很多问题所在,控件框架布局基本不变,主要是功能实现方法,反反复复修改了很多次,吸取了很多经验教训。

数据库连接信息,用SQL Server身份验证登录,记住登录名和密码。

SQL数据库连接

新建一个“账号登录”数据库,在里面创建一张“登录注册表”,设置好列名username、password和数据类型。

在这里插入图片描述

输入的密码采用了MD5加盐加密操作,所以password一栏显示为密文。

在这里插入图片描述

然后就是python窗体源代码了,我这里创建了5个Form窗体,包含了账号登录、账号注册、修改密码、账号注销四个功能。虽然这些功能函数和控件是相关联的,这里我还是拆分解析一下各部分代码功能。

我们首先来连接一下SQL Server数据库,记得要导入相关的安装包

import pymssql

# 数据库连接
conn = pymssql.connect('服务器名称', '登录名', '密码', '数据库名称', )
#例如:conn = pymssql.connect('WSDFERESQLEXPRESS', '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()  # 创建一个窗体Form1

Form1.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()  # 创建一个窗体Form1
Form2 = tkinter.Tk()  # 创建一个窗体Form2
Form3 = tkinter.Tk()  # 创建一个窗体Form3
Form4 = tkinter.Tk()  # 创建一个窗体Form4
Form5 = 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()来隐藏其他窗口,只显示一个登录窗口Form1
Form2.withdraw()  # 隐藏窗体Form2
Form3.withdraw()  # 隐藏窗体Form3
Form4.withdraw()  # 隐藏窗体Form4
Form5.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)  # 跳转主界面Form2
		else:
			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)  # 跳转登录界面Form1
	else:
		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()  # 隐藏窗体Form2
		Form3.withdraw()  # 隐藏窗体Form2
		Form4.withdraw()  # 隐藏窗体Form2
		Form5.withdraw()  # 隐藏窗体Form2
		Center(Form1)  # 窗体Form1居中显示
		Form1.deiconify()  # 窗体Form1显示
		text1.focus()  # 鼠标光标定位在文本输入框text1
	elif 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 hashlib
import sys
import tkinter
import tkinter.messagebox
from tkinter import *
import pymssql


class 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.__Form2
            self.__Form3.withdraw()  # 隐藏窗体self.__Form2
            self.__Form4.withdraw()  # 隐藏窗体self.__Form2
            self.__Form5.withdraw()  # 隐藏窗体self.__Form2
            self.__Center(self.__Form1)  # 窗体self.__Form1居中显示
            self.__Form1.deiconify()  # 窗体self.__Form1显示
            self.__text1.focus()  # 鼠标光标定位在文本输入框self.__text1
        elif 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.__Form1
        self.__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.__Form2
        else:
            tkinter.messagebox.showinfo("提示", "账号密码错误!")
            self.__text2.delete(0, tkinter.END)

    # 界面self.__Form3:注册功能
    def __Register(self):
        # 创建一个游标对象cur
        self.__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.__Form1
        except 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.__Form1
        except EXCEPTION as ex:
            tkinter.messagebox.showinfo("提示", "账号注销失败!")
            tkinter.messagebox.showinfo("提示", ex)
            self.__Clear5()

    def Main(self):
        self.__Form1 = tkinter.Tk()  # 创建一个窗体Form1
        self.__Form2 = tkinter.Tk()  # 创建一个窗体Form2
        self.__Form3 = tkinter.Tk()  # 创建一个窗体Form3
        self.__Form4 = tkinter.Tk()  # 创建一个窗体Form4
        self.__Form5 = tkinter.Tk()  # 创建一个窗体Form5

        self.__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()来隐藏其他窗口,只显示一个登录窗口Form1
        self.__Form2.withdraw()  # 隐藏窗体Form2
        self.__Form3.withdraw()  # 隐藏窗体Form3
        self.__Form4.withdraw()  # 隐藏窗体Form4
        self.__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窗体程序通过列表和字典来实现账号登录、注册、修改、注销等功能。

最后

以上就是满意草莓为你收集整理的Python Tkinter窗体程序连接SQL Server数据库实现账号登录、注册、修改、注销等功能(不定时更新)的全部内容,希望文章能够帮你解决Python Tkinter窗体程序连接SQL Server数据库实现账号登录、注册、修改、注销等功能(不定时更新)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(55)

评论列表共有 0 条评论

立即
投稿
返回
顶部