【Python】手把手教你用tkinter设计图书管理登录UI界面(五)

2023-12-14 23:48:53

上一篇:【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完善功能_3 import Retrieve


class Register(Retrieve):
    """继承Retrieve,设计新用户注册"""

    def __init__(self):
        """构造方法"""

        # 调用Retrieve的构造方法
        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

文章来源:https://blog.csdn.net/zhouhua2022/article/details/135005845
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。