【Python教程】使用tkinter设计图书管理系统登录界面(五)
上一篇:【Python】手把手教你用tkinter设计图书管理登录UI界面(四)-CSDN博客
下一篇:【Python】手把手教你用tkinter设计图书管理登录UI界面(六)-CSDN博客
本文主要实现本项目“新用户注册功能”,代码设计比较简陋,但基本的功能都完成了。
如果前面几篇的代码您都理解了,那么本篇文章自然就难不倒您,所以我就不详细赘述过程了。
假若您有疑问,欢迎在评论区交流!
运行结果
导入【图书管理系统项目.code.登录UI】模块
导入【图书管理系统项目.code.继承登录UI完善功能_1】模块
导入【图书管理系统项目.code.继承登录UI完善功能_2】模块
导入【图书管理系统项目.code.继承登录UI完善功能_3】模块
首位用户注册成功
继承登录UI完善功能_4.py
"""
继承登录UI完善功能_4 模块
"""
# 通配符 '*'
__all__ = ['Register']
import os, re, time, random
import tkinter as tk
from tkinter import ttk
import tkinter.messagebox as tkmb
from 图书管理系统项目.code.继承登录UI完善功能_2 import LoginUI_two
class Register(LoginUI_two):
"""继承LoginUI_two,设计新用户注册"""
def __init__(self):
"""构造方法"""
# 调用LoginUI_two的构造方法
super().__init__()
# 设计新用户注册
# 获取随机用户名数据库数据
self.getRandomUserNameData('..\\user_data\\随机用户名数据库.txt')
# 用户注册
self.registerButton.config(command=self.userRegister)
# 用户注册(UI)
def userRegister(self):
# 设计用户注册(UI)
self.registerUI = tk.Toplevel(self)
self.registerUI.title('用户注册')
self.registerUI.geometry(f'+{self.width//4}+{self.height//8}')
self.registerUI.resizable(0, 0) # 窗口大小禁止调节
self.registerUI.focus_force() # 窗口焦点
self.withdraw() # 隐藏主窗口(登录UI)
# 背景
self.registerBackgroundPhoto = tk.PhotoImage(file='..\\photo\\用户注册背景.png')
self.registerBackgroundButton = ttk.Button(self.registerUI, image=self.registerBackgroundPhoto)
self.registerBackgroundButton.pack(fill=tk.BOTH, expand=1)
# 输入格式错误提示
self.register_hintLabel = tk.Label(self.registerUI, text='输入格式错误提示', width=22)
# self.register_hintLabel.place(x=400, y=40)
# 新用户名
tk.Label(self.registerUI, text='新用户名').place(x=340, y=100)
# 用户名输入框
self.newUserVar = tk.StringVar()
self.newUserEntry = ttk.Entry(self.registerUI, textvariable=self.newUserVar, width=22)
self.newUserEntry.place(x=400, y=100)
# 随机用户名
self.register_randomButton = tk.Button(self.registerUI, image=self.randomPhoto, relief=tk.FLAT, command=self.randomUser)
self.register_randomButton.place(x=535, y=101)
# 设置密码
tk.Label(self.registerUI, text='设置密码').place(x=340, y=140)
# 输入设置密码
self.setPasswordVar = tk.StringVar()
self.setPasswordEntry = ttk.Entry(self.registerUI, textvariable=self.setPasswordVar, width=22)
self.setPasswordEntry.place(x=400, y=140)
# 确认密码
tk.Label(self.registerUI, text='确认密码').place(x=340, y=180)
# 再次输入密码
self.confirmPasswordVar = tk.StringVar()
self.confirmPasswordEntry = ttk.Entry(self.registerUI, textvariable=self.confirmPasswordVar, width=22)
self.confirmPasswordEntry.place(x=400, y=180)
# 手机号码
tk.Label(self.registerUI, text='手机号码').place(x=340, y=220)
# 输入手机号
self.registerPhoneVar = tk.StringVar()
self.registerPhoneEntry = ttk.Entry(self.registerUI, textvariable=self.registerPhoneVar, width=22)
self.registerPhoneEntry.place(x=400, y=220)
# 验证码
tk.Label(self.registerUI, text='验 证 码').place(x=340, y=260)
# 输入注册验证码
self.register_inputVerifyVar = tk.StringVar()
self.registerVerifyEntry = ttk.Entry(self.registerUI, textvariable=self.register_inputVerifyVar, width=10)
self.registerVerifyEntry.place(x=400, y=260)
# 显示验证码
self.showVerifyCode.set('获取验证码')
self.register_verifyButton = ttk.Button(self.registerUI, textvariable=self.showVerifyCode, width=9,
command=lambda: self.showVerifyCode.set(self.getVerifyCode()))
self.register_verifyButton.place(x=486, y=258)
# 确定注册
self.confirmButton = ttk.Button(self.registerUI, text='确定', command=self.registerUI_confirm)
self.confirmButton.place(x=340, y=320)
# 返回
self.register_returnButton = ttk.Button(self.registerUI, text='返回', command=self.registerUI_return)
self.register_returnButton.place(x=472, y=320)
# 窗口关闭触发
self.registerUI.protocol("WM_DELETE_WINDOW", self.registerUI_return)
# 限制输入内容
self.registerUI.bind('<KeyPress>', self.restrictInput)
# 确认注册
def registerUI_confirm(self):
"""print([self.newUserVar.get(), self.setPasswordVar.get(), self.confirmPasswordVar.get(), self.registerPhoneVar.get(),
self.register_inputVerifyVar.get(), self.showVerifyCode.get()])"""
self.register_hintLabel.place(x=400, y=40) # 显示错误提示标签内容
# 用户名输入空
if not self.newUserVar.get():
self.register_hintLabel.config(text=f'用户名不能为空', background='red')
self.newUserEntry.focus() # 设置焦点
# 密码输入空
elif not self.setPasswordVar.get():
self.register_hintLabel.config(text=f'密码不能为空', background='red')
self.setPasswordEntry.focus() # 设置焦点
# 确认密码输入空
elif not self.confirmPasswordVar.get():
self.register_hintLabel.config(text=f'确认密码不能为空', background='red')
self.confirmPasswordEntry.focus() # 设置焦点
# 手机号码输入空
elif not self.registerPhoneVar.get():
self.register_hintLabel.config(text=f'手机号码不能为空', background='red')
self.registerPhoneEntry.focus() # 设置焦点
# 验证码输入空
elif not self.register_inputVerifyVar.get():
self.register_hintLabel.config(text=f'验证码不能为空', background='red')
self.register_verifyButton.focus() # 设置焦点
# 判断输入两次密码是否相同
elif self.setPasswordVar.get() != self.confirmPasswordVar.get():
self.register_hintLabel.config(text=f'两次密码输入不一致', background='red')
self.confirmPasswordEntry.focus() # 设置焦点
# 判断输入手机号码长度是否为11位
elif len(self.registerPhoneVar.get()) != 11:
self.register_hintLabel.config(text=f'11位手机号码输入有误', background='red')
self.registerPhoneEntry.focus() # 设置焦点
# 判断验证码是否正确
elif not re.findall(self.showVerifyCode.get(), self.register_inputVerifyVar.get(), re.I):
self.register_hintLabel.config(text=f'6位验证码输入有误', background='red')
self.register_verifyButton.focus() # 设置焦点
# 判断已注册用户数据库是否为空
elif not self.userData:
# 注册成功
print('首位用户注册成功')
self.register_hintLabel.place_forget() # 隐藏错误提示标签内容
# 添加到数据容器内
self.userData.append([self.newUserVar.get(), self.setPasswordVar.get(), self.registerPhoneVar.get()])
# 写入文件数据库
self.write_register_user_data('..\\user_data\\已注册用户数据库.txt')
# 用户注册成功UI
self.register_user_succeed()
return
else:
# 查找用户名是否已注册
for name in self.userData:
# 如果已注册
if name[0] == self.newUserVar.get():
self.register_hintLabel.config(text=f'该用户名已注册', background='red')
self.newUserEntry.focus() # 设置焦点
break
# 如果已注册用户数据库找不到(则符合新用户)
elif name == self.userData[-1] and self.newUserVar.get():
# 注册成功
print('注册成功')
self.register_hintLabel.place_forget() # 隐藏错误提示标签内容
# 添加到数据容器内
self.userData.append([self.newUserVar.get(), self.setPasswordVar.get(), self.registerPhoneVar.get()])
# 写入文件数据库
self.write_register_user_data('..\\user_data\\已注册用户数据库.txt')
# 用户注册成功UI
self.register_user_succeed()
return
# 警告声与更新验证码
self.bell() # 警告声
self.showVerifyCode.set('获取验证码') # 验证码更新
self.register_hintLabel.place(x=400, y=40) # 显示错误提示标签内容
self.registerUI.update() # 窗口更新
time.sleep(1) # 睡眠1秒
self.register_hintLabel.place_forget() # 隐藏错误提示标签内容
# 用户注册成功UI
def register_user_succeed(self):
self.registerUI.bell() # 警告声
# 禁止窗口使用
self.registerUI.attributes("-disabled", True)
if tkmb.askokcancel('用户注册成功', f'恭喜您已注册成功!\n是否登录"{self.newUserVar.get()}"?'):
self.registerUI.destroy() # 销毁当前窗口
self.loginSucceedUI() # 登录成功
else:
self.registerUI.destroy() # 销毁当前窗口
self.registerUI_return() # 返回登录UI
# 写入文件数据库
def write_register_user_data(self, path):
# print(self.userData)
# 新用户数据写入文件
with open(path, 'w', encoding='utf-8') as file:
for user in self.userData:
file.write(f'{user[0]} {user[1]} {user[2]}\n')
# 限制输入内容
def restrictInput(self, event=None):
# print(event.widget, event.keysym)
# 用户名输入框限制
if str(event.widget) == '.!toplevel.!entry':
input_data = self.newUserVar.get()
# 匹配查找
chr_match = re.findall(' ', input_data)
# 不能输入特殊字符空格' ' 或 输入用户名字符个数不能大于10
if chr_match or len(input_data) > 10:
self.bell() # 警告声
# self.register_hintLabel.config(text='用户名格式无效', background='red')
self.register_hintLabel.place(x=400, y=40)
# 删除无效字符
# 不能输入特殊字符空格' '
if chr_match:
self.register_hintLabel.config(text='用户名格式无效空格" "', background='red')
self.newUserVar.set(input_data[:-len(chr_match):])
# 输入用户名字符个数不能大于10
elif len(input_data) > 10:
self.register_hintLabel.config(text='用户名超过命名最大长度', background='red')
self.newUserVar.set(input_data[:10:])
self.registerUI.update() # 更新窗口
time.sleep(1) # 睡眠1秒
self.register_hintLabel.place_forget()
# 设置密码输入框限制
elif str(event.widget) == '.!toplevel.!entry2':
input_data = self.setPasswordVar.get()
# 匹配查找
chr_match = re.findall(' ', input_data)
chinese_match = re.findall(r'[\u4ee0-\u9fff]', input_data)
# 不能输入特殊字符空格' ' 或 不能输入中文 或 输入密码个数不能大于10
if chr_match or chinese_match or len(input_data) > 10:
self.bell() # 警告声
# self.register_hintLabel.config(text='密码格式无效', background='red')
self.register_hintLabel.place(x=400, y=40)
# 删除无效字符
# 不能输入特殊字符空格' '
if chr_match:
self.register_hintLabel.config(text='密码格式无效空格" "', background='red')
self.setPasswordVar.set(input_data[:-len(chr_match):])
# 不能输入中文
elif chinese_match:
self.register_hintLabel.config(text='密码格式无效中文', background='red')
self.setPasswordVar.set(input_data[:-len(chinese_match):])
# 输入密码个数不能大于10
elif len(input_data) > 10:
self.register_hintLabel.config(text='密码超过最大设置长度', background='red')
self.setPasswordVar.set(input_data[:10:])
self.registerUI.update() # 更新窗口
time.sleep(1) # 睡眠1秒
self.register_hintLabel.place_forget()
# 确认输入密码框限制
elif str(event.widget) == '.!toplevel.!entry3':
input_data = self.confirmPasswordVar.get()
# 匹配查找
chr_match = re.findall(' ', input_data)
chinese_match = re.findall(r'[\u4ee0-\u9fff]', input_data)
# 不能输入特殊字符空格' ' 或 不能输入中文 或 输入密码个数不能大于10
if chr_match or chinese_match or len(input_data) > 10:
self.bell() # 警告声
# self.register_hintLabel.config(text='确认密码格式无效', background='red')
self.register_hintLabel.place(x=400, y=40)
# 删除无效字符
# 不能输入特殊字符空格' '
if chr_match:
self.register_hintLabel.config(text='确认密码格式无效空格" "', background='red')
self.confirmPasswordVar.set(input_data[:-len(chr_match):])
# 不能输入中文
elif chinese_match:
self.register_hintLabel.config(text='确认密码格式无效中文', background='red')
self.confirmPasswordVar.set(input_data[:-len(chinese_match):])
# 输入密码个数不能大于10
elif len(input_data) > 10:
self.register_hintLabel.config(text='确认密码超过最大设置长度', background='red')
self.confirmPasswordVar.set(input_data[:10:])
self.registerUI.update() # 更新窗口
time.sleep(1) # 睡眠1秒
self.register_hintLabel.place_forget()
# 输入手机号框限制(仅限大陆手机号码11位)
elif str(event.widget) == '.!toplevel.!entry4':
input_data = self.registerPhoneVar.get()
# 匹配查找
chr_match = re.findall(r'\D', input_data)
# 只能输入数字1-9 或 不能输入中文 或 手机号码个数不能大于11
if chr_match or len(input_data) > 11:
self.bell() # 警告声
# self.register_hintLabel.config(text='确认密码格式无效', background='red')
self.register_hintLabel.place(x=400, y=40)
# 删除无效字符
# 只能输入数字1-9
if chr_match:
self.register_hintLabel.config(text='手机号码仅限数字1-9', background='red')
self.registerPhoneVar.set(input_data[:-len(chr_match):])
# 手机号码个数不能大于11
elif len(input_data) > 11:
self.register_hintLabel.config(text='手机号码超过最大长度', background='red')
self.registerPhoneVar.set(input_data[:11:])
self.registerUI.update() # 更新窗口
time.sleep(1) # 睡眠1秒
self.register_hintLabel.place_forget()
# 验证码输入框限制
elif str(event.widget) == '.!toplevel.!entry5':
input_data = self.register_inputVerifyVar.get()
# 匹配查找
chr_match = re.findall(r'\w', input_data)
chinese_match = re.findall(r'[\u4ee0-\u9fff]', input_data)
# 不能输入特殊字符,除了下划线'_' 或 不能输入中文 或 输入验证码个数不能大于6
if len(chr_match) != len(input_data) or chinese_match or len(input_data) > 6:
self.bell() # 警告声
# self.register_hintLabel.config(text='验证码格式无效', background='red')
self.register_hintLabel.place(x=400, y=40)
# 删除无效字符
# 不能输入特殊字符,除了下划线'_'
if len(chr_match) != len(input_data):
self.register_hintLabel.config(text='验证码格式无效特殊符号', background='red')
self.register_inputVerifyVar.set(input_data[:len(chr_match):])
# 不能输入中文
elif chinese_match:
self.register_hintLabel.config(text='验证码格式无效中文', background='red')
self.register_inputVerifyVar.set(input_data[:-len(chinese_match):])
# 输入验证码个数不能大于6
elif len(input_data) > 6:
self.register_hintLabel.config(text='验证码超过最大长度', background='red')
self.register_inputVerifyVar.set(input_data[:6:])
self.registerUI.update() # 更新窗口
time.sleep(1) # 睡眠1秒
self.register_hintLabel.place_forget()
# 获取随机用户名数据库数据
def getRandomUserNameData(self, path):
# 随机用户名容器
self.randomName = []
# 判断数据库文件是否存在
if os.path.exists(path):
# 读取随机用户名数据库数据
with open(path, encoding='utf-8') as file:
for line in file:
if line != '\n':
self.randomName.extend(line.split())
# print(self.randomName)
# 随机用户名
def randomUser(self, event=None):
# 判断数据库是否不为空
if self.randomName:
# 插入用户名
self.newUserVar.set(random.choice(self.randomName))
return
self.register_hintLabel.place(x=400, y=40) # 显示错误提示标签内容
self.bell() # 警告声
self.register_hintLabel.config(text='随机用户名数据库为空', background='red') # 输入错误提示语
self.registerUI.update() # 窗口更新
time.sleep(1) # 睡眠1秒
self.register_hintLabel.place_forget() # 隐藏错误提示标签内容
# 返回登录UI
def registerUI_return(self):
self.deiconify() # 显示主窗口(登录UI)
self.registerUI.destroy() # 销毁当前窗口
# 初始化数据
self.showVerifyCode.set('获取验证码')
self.showOrConcealCount = 0 # 默认是密码隐藏
# 代码测试
if __name__ == '__main__':
ui = Register() # 对象实例化
ui.mainloop() # 窗口主循环
else:
print(f'导入【{__name__}】模块')
作者:周华
创作日期:2023/12/14
作者:周华2022