200行代码帮你实现界面化登录注册功能

今天我们将利用 tkinter 库制作以下的登录界面, 可以实现登录,并可以实现注册和登录,这里为了简单起见,使用 json文件保存读取用户账号和密码

200行代码帮你实现界面化登录注册功能_第1张图片
200行代码帮你实现界面化登录注册功能_第2张图片

创建根窗口

首先,我们需要建立一个根窗口,控制其不能够缩放并设置其标题,调用mainloop方法来控制

from tkinter import *
window = Tk()  # 建立根目录
window.title("Welcome")  # 设置标题
window.geometry("500x400")  # 设置窗口的大小
window.resizable(width=False, height=False)  # 设置窗口不能够缩放
window.mainloop()

到此,我们运行一下,便可以得到如下的效果

200行代码帮你实现界面化登录注册功能_第3张图片

添加图片

然后我们来设置一下首页中图片,利用PILCanvas中的create_image方法加上控制一下位置,我们便可以实现,代码如下:

from PIL import Image, ImageTk
# 首页的图片
image = Image.open("./welcome.jpg")  # 打开图片,保存在image对象中
img = ImageTk.PhotoImage(image)  # 转化成tkinter中的图片对象
c = Canvas(window, width=500, height=200)  # 创建画布对象
c.create_image(250, 0, image=img, anchor=N)  # 添加图片
c.pack()  # 将图片打包到首页上

就这样就,我们实现了如下的效果

200行代码帮你实现界面化登录注册功能_第4张图片

添加文字信息

接下来我们就需要在上面添加文字信息,在tkinter中提供了一个类Label可以为我们做这件事,常见用法如下

Label(master[, text, font,textvariabel, wraplength, padx, pady, ...])
  • master是要显示的窗口
  • text为要显示的文字
  • font为要显示的文字的字体,可以控制字体的大小
  • textvariable文字变量,以文字变量的值显示
  • wraplength换行的长度
  • padx, pady 内容区与边界的距离

知道了这些之后,我们便可以在之前的窗口上添加这些文字了,然后使用place将这些控件摆放在对应的位置

username_label = Label(window, font='Monaco 12', text="username:")
passwd_label = Label(window, font='Monaco 12', text='password:')

username_label.place(x=40, y=220)  # 摆放位置
passwd_label.place(x=40, y=260)

welcome = Label(window, font="monaco 12", text='Welcome here to learn python !')
welcome.place(x=250, y=320, anchor=N)

创建输入框

那么输入框如何解决呢,在tkinter中提供了Entry控件可以获取用户的输入,用法见下:

Entry(master, [textvariable, width, show, font, padx, pady, ...])
  • master是要显示的窗口
  • show 为输入显示的字符,默认为None,即显示原字符
  • font为要显示的文字的字体,可以控制字体的大小
  • textvariable文字变量,输入的值可以保存在该变量之中
  • width 输入框的宽度
  • padx, pady 内容区与边界的距离

定义相关变量

tkinter中有定义好的变量类型对象 – BooleanVar, DoubleVar, IntVar, StringVar 分别可以保存布尔类型,浮点数类型,整数类型以及字符串类型的变量,使用的时候,我们可以使用其中的set方法来赋值,使用get方法来获取其中的值,使用这些变量通常会在交互中需要改变某个变量的值,比如输入,选择等

知道了以上这些之后,我们便可以用来实现处理用户输入了,代码如下:

# 输入框
username = StringVar()
passwd = StringVar()
# 以下将用户输入的内容赋值给我们的变量
username_entry = Entry(window, font='Monaco 10', width=20, textvariable=username)
passwd_entry = Entry(window, font='Monaco 10', width=20, textvariable=passwd, show='*')  
username_entry.place(x=150, y=225)
passwd_entry.place(x=150, y=265)

创建按钮

做到这里,效果已经出来了,我们还需要添加两个按钮来实现登录和注册,在tkinterButton可以为我们服务,使用方法如下:

Button(master [, text, font, command, width, borderwidth...])
  • master是要显示的窗口
  • text为要显示的文字
  • font为要显示的文字的字体,可以控制字体的大小
  • command为点击之后执行的函数
  • width为按钮的宽度
  • borderwidth 为边框的宽度

于是,我们可以使用这样的代码来添加我们的按钮

login_button = Button(window, width=8, text='Login in', font='Monaco 10', borderwidth=1, command=None)

sign_up_buttom = Button(window, width=8, text='Sign up', font='Monaco 10', borderwidth=1, command=None)

login_button.place(x=360, y=260)
sign_up_buttom.place(x=360, y=220)

做到这里,图形的界面已经快完成了,效果如下

200行代码帮你实现界面化登录注册功能_第5张图片

创建弹窗

接下来我们需要具体的实现其功能,首先我们来实现注册功能

注册的时候,我们应该再弹出一个小窗来负责这一部分,在tkinter中提供了Toplevel对象可以帮我们实现,Toplevel对象就类似与Tk一样,是一个相对独立,拥有和Tk一样结构的窗口,所以首先我们可以和之前一样来设置一下这个弹窗的属性,并对其进行添加其他控件

# 图片的定义,应该为全局变量
img_2 = Image.open("./sign_up.jpg")
img_2 = ImageTk.PhotoImage(img_2)
win = Toplevel()  # 创建一个顶层窗口
win.resizable(width=False, height=False)  # 设置窗口不能缩放
win.title("Sign up")  # 设置标题
win.geometry('400x300')  # 设置窗口的大小
win.wm_attributes('-topmost', -1)  # 使得该窗口位于页面的最顶端
win_c = Canvas(win)
win_c.create_image(190, 150, image=img_2)  # 绘制图片
win_c.pack() # 打包

prompt = Label(win, text='Cyberist -- a python learner', font='Monaco 8')
prompt.place(x=100, y=270)

# 提示信息 账号 密码 密码确认
user_label = Label(win, text='username:', font='monaco 10', bg=None)
pwd_label = Label(win, text='password:', font='monaco 10')
pwd_confirm_label = Label(win, text='confirm:', font='monaco 10')
# 摆放这些标签,放在合适的位置
user_label.place(x=20, y=180)
pwd_label.place(x=20, y=210)
pwd_confirm_label.place(x=20, y=240)
# 定义变量获取用户的输入信息
new_user = StringVar()
new_passwd = StringVar()
new_passwd_confirm = StringVar()
# 输入框选项设置
user_entry = Entry(win, font='Monaco 12', width=20, textvariable=new_user)
passwd_entry = Entry(win, font='Monaco 12', width=20, textvariable=new_passwd, show='*')
passwd_confirm_entry = Entry(win, font='Monaco 12', width=20, textvariable=new_passwd_confirm, show='*')
# 摆放好这些输入框的位置
user_entry.place(x=100, y=180)
passwd_entry.place(x=100, y=210)
passwd_confirm_entry.place(x=100, y=240)
# 根据之前在登录界面的用户名填写 uername为之前定义的变量,这里的代码只是为了简便用户的操作,
# 这样在操作的时候就不用输入之前的用户名来实现注册
tmp_username = username.get()
new_user.set(tmp_username)
# 定义按钮,设置位置
sign_up_button = Button(win, text='sign up', font='Monaco 10', command=write_in)
sign_up_button.place(x=310, y=210)

运行之后我们可以得到这样的效果,于是离我们的最终的效果又近了一步

200行代码帮你实现界面化登录注册功能_第6张图片

定义好了这样的一个窗口,我们应该将其打包成一个函数,然后在用户点击注册的时候弹出这样的窗口,加入这样定义的函数名称为sign_up,于是我们需要修改一下之前sign_up_button的属性

sign_up_buttom = Button(window, width=8, text='Sign up', font='Monaco 10', borderwidth=1, command=sign_up)  # 调用sign_up函数

这样只要我们一点击sign_up_button便可以弹出这个窗口,对于login_in按钮,我们需要对用户的输入进行判断,在已经注册号的用户中查找对应信息,如果没有找到账号,提示该用户没有注册,是否注册,如果密码输入错误,提示密码错误

创建信息提示窗口

tkintermessagebox可以帮我们提供许多信息弹窗:

  • showinfo 向用户显示信息
  • showerror 显示错误
  • showwarning 显示警告
  • askquestion 向用户提问,可选择yesno的问题
  • askokcancel 提示选择
  • askyesno 提示选择
  • askyesnocancel 提示选择
  • askretrycancel 提示选择

具体用法一致,可以使用下列参数

  • title 提示窗口的标题
  • message 需要显示的信息
  • icon 只能为messagebox中定义好的error, info, question, or warning
  • detail 详细的信息
  • default 只能为messagebox中定义的abort, retry, ignore, ok, cancel, no, oryes, 部分窗口没有该参数, 如showinfo, showerror , showwarning

实例使用如下:

from tkinter import messagebox
# 显示信息一类
messagebox.showinfo(title='Python', message='Welcome here to learn python',icon=messagebox.INFO, detail='Created by Cyberist' )
messagebox.showerror(title='Error', message='Do not click me', icon=messagebox.ERROR, detail='Created by Cyberist')
messagebox.showwarning(title='Warning', message='You have made a bug, go and fix it', detail='Created by Cyberist', icon=messagebox.WARNING)

# 获取用户信息类
messagebox.askokcancel(title='Choice', message='Do you want to continue', icon=messagebox.INFO, detail='Created by Cyberist', default=messagebox.OK)
messagebox.askquestion(title='Question', message='Do you want to continue', icon=messagebox.QUESTION, detail='Created by Cyberist', default=messagebox.YES )
messagebox.askretrycancel(title='Ask', message='You network does not work properly, do you want to try again', detail="Created by Cyberist", default=messagebox.RETRY)
messagebox.askyesnocancel(title='Ask', message='Start to download this', default=messagebox.YES)
messagebox.askyesno(title='Choice', message='Do you want to install this app', default=messagebox.YES)

通过这些学习,那么我们可以实现登录的这个功能了,文件的操作异常处理这个大家现在不用着急,之后会用教程详细讲解的,关于json库,也会在小知识点中进行讲解,届时进行关注便可~

于是我们可以得到一下的代码:

# 提交登录功能实现
def login():
    user = username.get()  # 获取用户输入的账号密码
    password = passwd.get()
    if str(user) and str(password): # 如果不是空的,则进行查找,如果是空的,则提示填充输入框
        try:
            with open('./data.json', 'r') as file:  # 打开保存用户的账号密码的文件
                data = json.load(file)  # 加载文件并保存为json类型
                if user in data:
                    if password == data[user]:
                        # 账号密码对上,输入登录成功
                        messagebox.showinfo(title='Successfully', message="Login in susscessfully")
                        """
                        登录成功后可以在这里进行操作, 这里便不添加其他的功能了
                        """
                    else:
                        # 密码输入错误,提示
                        messagebox.showerror(title='Error', message='password is wrong')
                else:
                    # flag 可以保存用户的操作信息,如果选择的yes,则flag为True
                    flag = messagebox.askyesno(title='sign up',
                                               message='You have not signed up, do you want to sign up')
                    if flag:
                        # 如果是,则进行注册
                        sign_up()
                    else:
                        # 否则的话,退出
                        window.destroy()
        except:
            # 打开文件错误,重新打开,并输入默认的账号密码
            with open('./data.json', 'w') as file:
                admin = {"admin": "Cyberist"}
                json.dump(admin, file)
    else:
        # 没有填充输入框,提示错误
        messagebox.showerror(title="Error", message='Fill in all the blank')

之间我们还有一个sign_up的功能需要实现, sign_up的界面设计在之前就已经实现了,我们现在需要实现的便是如何具体的实现的功能,其实思路比较清晰, 首先我们需要获取用户的输入,判断两次输入的密码是否正确,如果正确保存信息,否则提示重新输入,具体代码如下, 我们将其定义为write_in函数:

def write_in():
        # 如果输入的不是空的
        if str(new_passwd.get()) and str(new_user.get()) and str(new_passwd_confirm.get()):
            if new_passwd_confirm.get() == new_passwd.get():
                # 如果两次输入的密码正确,在进行之下操作
                try:
                    file = open("./data.json", "r")
                    data = json.load(file)
                    file.close()
                    if str(new_user.get()) in data:
                        messagebox.showinfo(title='Error', message='The username has been signed')
                    else:
                        file_2 = open("./data.json", "r")
                        user = str(new_user.get())
                        passwd = new_passwd.get()
                        data[user] = passwd
                        with open('./data.json', 'w') as file_3:
                            json.dump(data, file_3)
                        messagebox.showinfo(message="Sign up finished", title='Successfully')
                        win.destroy()
                except Exception as e:
                    pass
            else:
                messagebox.showerror(title='Error', message='The confirmed password is not right !')
        else:
            messagebox.showerror(title='Error', message='Fill in all the blank !')

然后我们只需要将该函数被sign_up按钮调用便可

sign_up_button = Button(win, text='sign up', font='Monaco 10', command=write_in) # 调用write_in函数

到这里,我们的功能实现便已经完成了,登录的功能也具体实现1了,但是其实这些代码还是可以改进的,比如不用json格式来保存用户的账号密码信息,而是使用pickle库,这样用户的账号密码不会以明文的形式暴露出来,提高其安全性。此外,我们还可以对我们的界面进行自定义的美化,你想如何做,便如何做。

另外在这里提供了其中图片的下载, 并对其中的图片进行了操作

import requests
import os 
from PIL import Image
"""
下载相关的图片,并对图片进行缩放等操作
"""

def download(url):
    response = requests.get(url)
    return response.content


def get_image():
    url1= 'https://marketplace.canva.com/MADeqzsTN80/1/screen_2x/canva-sign-up-username-password-log-in-MADeqzsTN80.jpg'

    url2 = 'https://images.unsplash.com/photo-1460467820054-c87ab43e9b59?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1561&q=80'

    if os.path.exists('welcome.jpg'):
        os.remove("welcome.jpg")

    if os.path.exists('sign-up.jpg'):
        os.remove('sign-up.jpg')

    content1 = download(url2)

    content2 = download(url1)

    with open('./welcome.jpg', 'wb') as file:
        file.write(content1)

    with open('./sign_up.jpg', 'wb') as file:
        file.write(content2)


    def change(img_path,width, height):
        img = Image.open(img_path)
        img.thumbnail((width, height), resample=Image.LANCZOS)
        img.save( img_path)

    change('welcome.jpg', 265,200)
    change("sign_up.jpg", 500,333)
    

def main():
    get_image()

当然是用tkinter也只是做图形的一种方法,自己对前端也是比较感兴趣,之后可能推出更多的相关教程,敬请关注

200行代码帮你实现界面化登录注册功能_第7张图片


  1. 完整代码请在公众号内回复关键词登录界面即可以获取, 代码已进行包装 ↩︎

你可能感兴趣的:(#,python,基础,python)