Python中Tkinter设计用户登录和注册界面(第13节)


我们在设计一款应用程序时,用户登录和注册界面是程序必不可少的部分。无论是网站还是桌面应用程序,用户认证都是保证安全性的基础。本节教程中,我们将通过Python自带的Tkinter库创建一个简单的用户登录和注册界面,用户成功登录后会弹出“欢迎用户”的对话框。

1、用户登录和注册界面程序介绍

用户登录和注册界面的背景图片采用渐变形式,由于Tkinter本身并不直接支持背景渐变,所以我们使用PIL库来创建渐变图像,然后将其用作Tkinter窗口的背景。

当用户注册成功后,会在工作目录下创建一个user.pickle文件,用于保存用户的账号和密码,下次打开程序时将自动从本地的user.pickle文件中获取用户信息。

2、用户登录和注册界面程序演示

Python中Tkinter设计用户登录和注册界面

Python中Tkinter设计用户登录和注册界面

3、代码实现

(1)安装Pillow库

首先,确保你已经安装了Pillow库。如果还没有安装,可以通过pip安装:

pip install pillow

(2)导入必要的库

import tkinter as tk
from tkinter import messagebox
import os, pickle
from PIL import Image, ImageTk, ImageDraw

这里导入了tkinter库用于创建GUI应用图形界面,tkinter的messagebox用于消息提示。os库用于文件和文件夹操作。pickle模块可以将几乎所有的Python对象保存到文件中,下次打开程序时可以直接加载保存的文件。pickle模块在数据持久化、进程间通信、分布式计算等场景中非常有用,可以将复杂的数据结构保存到文件中,以便长期存储或在不同程序之间共享数据。

(3)用户登录和注册界面程序的完整代码如下所示

动手练一练:

import tkinter as tk
from tkinter import messagebox
import os, pickle
from PIL import Image, ImageTk, ImageDraw

# 获取当前脚本文件所在的目录
default_directory = os.path.dirname(os.path.abspath(__file__))
# 将当前脚本文件所在的目录设置为工作目录
os.chdir(default_directory)

# 定义“user.pickle”文件,用于保存注册数据
file_path = 'user.pickle'

# 创建渐变效果函数
def create_gradient_image(width, height, color1, color2):
    image = Image.new('RGB', (width, height))
    draw = ImageDraw.Draw(image)
    for i in range(width):
        color = tuple(int(c1 + (c2 - c1) * i / width) for c1, c2 in zip(color1, color2))
        draw.line((i, 0, i, height), fill=color)
    return image

# 创建登录窗口
app = tk.Tk()
app.title('用户登录界面')
# 设置登录窗口居中
window_height = 350
window_width = 300
screen_width = app.winfo_screenwidth()
screen_height = app.winfo_screenheight()
x = (screen_width - window_height) / 2
y = (screen_height - window_width) / 2
app.geometry('%dx%d+%d+%d' % (window_height, window_width, x, y))
app.resizable(width=False, height=False)
# 背景创建渐变图像,并转换为PhotoImage对象
gradient_image = create_gradient_image(350, 300, (187, 255, 255), (119, 221, 255))
photo_login = ImageTk.PhotoImage(gradient_image)
label_bg = tk.Label(app, image=photo_login)
# 保持对photo_login的引用,防止被垃圾回收器回收
label_bg.image = photo_login
label_bg.pack(side='top')

# 创建用户名和密码标签
tk.Label(app, text='用户名:', bg='#a7f5ff').place(x=80, y=80)
tk.Label(app, text='密码:', bg='#a7f5ff').place(x=80, y=120)
# 创建用户名输入框
var_user_name = tk.StringVar()
user_name_entry = tk.Entry(app, textvariable=var_user_name)
user_name_entry.place(x=140,y=80)
# 创建密码输入框
var_user_password = tk.StringVar()
user_password_entry = tk.Entry(app, textvariable=var_user_password,show='*')
user_password_entry.place(x=140,y=120)

# 用户登录函数
def make_login():
    # 获取用户输入的信息
    user_name = var_user_name.get()
    user_password = var_user_password.get()
    # 从本地字典获取用户信息,如果文件不存在,则创建文件
    try:
        with open(file_path,'rb') as usr_file:
            user_information=pickle.load(usr_file)
    except FileNotFoundError:
        with open(file_path,'wb') as usr_file:
            user_information={'admin':'admin'}
            pickle.dump(user_information,usr_file)
    # 用户输入的数据和保存的数据进行对比
    if user_name in user_information:
        if user_password == user_information[user_name]:
            messagebox.showinfo(title='welcome', message='欢迎您:' + user_name)
        else:
            messagebox.showerror(message='密码错误')
    # 判断用户名和密码不能为空
    elif user_name=='' or user_password=='' :
        messagebox.showerror(message='用户名或密码为空')
    # 如果用户名不在“user.pickle”中,则弹出是否注册的对话框
    else:
        is_signup=messagebox.askyesno('欢迎','您还没有注册,是否现在注册')
        if is_signup:
            register()
# 创建注册函数
def register():
    # 点击确认注册触发的函数
    def confirm_register():
        # 获取用户输入的内容
        n_name=new_name.get()
        n_password=new_password.get()
        n_repassword=new_repassword.get()

        # 获取“user.pickle”中已有的用户信息,如果未找到用户信息,则用户信息设为空
        try:
            with open(file_path,'rb') as usr_file:
                user_information=pickle.load(usr_file)
        except FileNotFoundError:
            user_information={}           

        # 检查用户名是否存在、密码是否为空、两次密码输入是否一致
        if n_name in user_information:
            messagebox.showerror('错误','该用户名已存在,请填写其它用户名')
        elif n_password =='' or n_name=='':
            messagebox.showerror('失败!','用户名或密码不能为空')
        elif n_password !=n_repassword:
            messagebox.showerror('失败!', '注册失败,两次输入的密码不一致!')
        # 如果注册信息正常,则将用户名和密码写入“user.pickle”
        else:
            user_information[n_name]=n_password
            with open(file_path,'wb') as usr_file:
                pickle.dump(user_information,usr_file)
            messagebox.showinfo('欢迎','注册成功')
            # 如果注册成功,则关闭注册框
            window_app_register.destroy()
    # 创建注册界面
    window_app_register=tk.Toplevel(app)
    window_app_register.title('用户注册')
    # 设置注册窗口居中
    window_height = 350
    window_width = 300
    screen_width = window_app_register.winfo_screenwidth()
    screen_height = window_app_register.winfo_screenheight()
    x = (screen_width - window_height) / 2
    y = (screen_height - window_width) / 2
    window_app_register.geometry('%dx%d+%d+%d' % (window_height, window_width, x, y))
    window_app_register.resizable(width=False, height=False)
    # 背景创建渐变图像并转换为PhotoImage对象
    gradient_image = create_gradient_image(350, 300, (187, 255, 255), (119, 221, 255))
    photo_register = ImageTk.PhotoImage(gradient_image)
    label_bg = tk.Label(window_app_register, image=photo_register)
    # 保持对photo_register的引用,防止被垃圾回收器回收
    label_bg.image = photo_register
    label_bg.pack(side='top')

    # 创建用户名标签和输入框
    new_name=tk.StringVar()
    tk.Label(window_app_register,text='用户名:',bg='#a7f5ff').place(x=50,y=60)
    tk.Entry(window_app_register,textvariable=new_name).place(x=160,y=60)
    # 创建密码标签和输入框
    new_password=tk.StringVar()
    tk.Label(window_app_register,text='请输入密码:',bg='#a7f5ff').place(x=50,y=100)
    tk.Entry(window_app_register,textvariable=new_password,show='*').place(x=160,y=100)    
    # 创建再次确认密码标签和输入框
    new_repassword=tk.StringVar()
    tk.Label(window_app_register,text='再次确认密码:',bg='#a7f5ff').place(x=50,y=140)
    tk.Entry(window_app_register,textvariable=new_repassword,show='*').place(x=160,y=140)    
    # 创建确认注册按钮
    tk.Button(window_app_register,text='确认注册',command=confirm_register).place(x=140,y=190)

# 创建退出函数
def user_quit():
    app.destroy()

# 创建页面中登录和注册按钮
login_button=tk.Button(app,text='登录',command=make_login)
login_button.place(x=100,y=180)
register_button=tk.Button(app,text='注册',command=register)
register_button.place(x=170,y=180)
quit_button=tk.Button(app,text='退出',command=user_quit)
quit_button.place(x=240,y=180)

# 运行主循环
app.mainloop()