本文讲解 tkinter
实践 如何注册用户及登陆 1。
Updated: 2022 / 10 / 8
利用 tkinter
实现用户的注册及登陆,要求对 tkinter
已掌握一定的基础知识。
思路
- 登陆 -> 判断用户账号及密码是否正确 -> 成功登陆
- 注册 -> 判断是否需要注册新用户 -> 注册完毕 -> 成功登陆
实现
设置画布
准备一张图片,作为登陆界面的背景图片,可暂时命名为 background.png
。
在本文中,使用以下所示图片:
import tkinter as tk
from PIL import Image, ImageTk
root = tk.Tk()
root.title('Log in')
root.geometry('450x300+500+250')
# 以上,创建窗口对象、设置窗口标题和窗口尺寸及位置;
canvas = tk.Canvas(root, height=300, width=450)
# 创建画布对象、设置画布的尺寸;
image = Image.open("background.png")
# 打开要放到画布上的背景图片
im = ImageTk.PhotoImage(image)
bg = canvas.create_image(0, 0, anchor='nw', image=im)
# 将背景图片放到画布上
canvas.pack(side='top')
# 将画布归置到最上方
root.mainloop()
效果如下,
业务逻辑
对于未注册用户,需先进行注册才能进行登录;
对于已注册用户,需验证其用户名及密码信息正确与否然后进行登陆。
信息保存
usrs_info.pickle
是注册成功后生成的文件 1,用于保存注册用户的信息。
def sign():
# get data
np = newpw.get()
npf = newpw_confirm.get()
nn = newun.get()
# judge if data has already been registered;
with open('usrs_info.pickle', 'rb') as usr_file:
exist_usr_info = pickle.load(usr_file)
if np != npf:
tk.messagebox.showerror(title='Error', message='Confirm Your Password !')
elif nn in exist_usr_info:
tk.messagebox.showerror(title='Error', message='This username has been registered !')
else:
exist_usr_info[nn] = np
with open('usrs_info.pickle', 'wb') as usr_file:
# write username and password in user_info_pickle file in the format of dict
pickle.dump(exist_usr_info, usr_file)
tk.messagebox.showinfo(title='Welcome', message=f"Your register with '{nn}', '{np}' successfully.")
# destory top level window
win_signup.destroy()
示例
import tkinter as tk
from tkinter import messagebox
from PIL import Image, ImageTk
import pickle
### create root object
root = tk.Tk()
root.title('Log in')
root.geometry('450x300+500+250')
### create canvas
canvas = tk.Canvas(root, height=300, width=450)
im = Image.open("background1.png")
bgimage = ImageTk.PhotoImage(im)
image = canvas.create_image(0, 0, anchor='nw', image=bgimage)
canvas.pack(side='top')
# place the canvas to the top
### create labels and entries;
tk.Label(root, text='Username').place(x=80, y=100)
tk.Label(root, text='Password').place(x=80, y=150)
varUN = tk.StringVar()
varUN.set('123@gmail.com')
varPW = tk.StringVar()
entryUN = tk.Entry(root, textvariable=varUN)
entryUN.place(x=160, y=100)
entryPW = tk.Entry(root, textvariable=varPW, show='*')
entryPW.place(x=160, y=150)
### log in event bind to button Log in
def usr_login():
global un
un = varUN.get()
pw = varPW.get()
# if pickle file exists, load it; else, generate it;
try:
with open('usrs_info.pickle', 'rb') as usr_file:
usrs_info = pickle.load(usr_file)
except FileNotFoundError:
with open('usrs_info.pickle', 'wb') as usr_file:
usrs_info = {'admin': 'admin'}
pickle.dump(usrs_info, usr_file)
if un in usrs_info:
if pw == usrs_info[un]:
tk.messagebox.showinfo(title='Welcome', message=un + ':Log in successfully.')
else:
tk.messagebox.showinfo(message='Error:Please retry with your password.')
else:
is_sign_up = tk.messagebox.askyesno('Info', 'Please register your personal account first.')
if is_sign_up:
usr_sign_up()
### sign up event bind to button sign up
def usr_sign_up():
def sign():
# get data
np = new_pwd.get()
npf = new_pwd_confirm.get()
nn = new_name.get()
# judge if data has already been registered;
with open('usrs_info.pickle', 'rb') as usr_file:
exist_usr_info = pickle.load(usr_file)
if np != npf:
tk.messagebox.showerror('Error', 'Confirm Your Password !')
elif nn in exist_usr_info:
tk.messagebox.showerror('Error', 'This username has been registered !')
else:
exist_usr_info[nn] = np
with open('usrs_info.pickle', 'wb') as usr_file:
# write username and password in user_info_pickle file in the format of dict
pickle.dump(exist_usr_info, usr_file)
tk.messagebox.showinfo('Welcome', "Your register with '%s', '%s' successfully." % (nn, np))
# destory top level window
window_sign_up.destroy()
window_sign_up = tk.Toplevel(root)
window_sign_up.title('Welcome to Register')
window_sign_up.geometry('450x300+500+250') # 中间是x,而不是*号
new_name = tk.StringVar()
new_name.set(un)
tk.Label(window_sign_up, text='Username').place(x=30, y=80)
entry_new_name = tk.Entry(window_sign_up, textvariable=new_name)
entry_new_name.place(x=160, y=80)
new_pwd = tk.StringVar()
tk.Label(window_sign_up, text='Password').place(x=30, y=120)
entry_usr_pwd = tk.Entry(window_sign_up, textvariable=new_pwd, show='*')
entry_usr_pwd.place(x=160, y=120)
new_pwd_confirm = tk.StringVar()
tk.Label(window_sign_up, text='Confirm password').place(x=30, y=160)
entry_usr_pwd_confirm = tk.Entry(window_sign_up, textvariable=new_pwd_confirm, show='*')
entry_usr_pwd_confirm.place(x=160, y=160)
btn_confirm_sign_up = tk.Button(window_sign_up, text='Sign Up ', command=sign)
btn_confirm_sign_up.place(x=160, y=220)
btn_login = tk.Button(root, text='Log In', command=usr_login)
btn_login.place(x=150, y=230)
btn_sign_up = tk.Button(root, text='Sign Up', command=usr_sign_up)
btn_sign_up.place(x=250, y=230)
root.mainloop()
如果改写成封装式,需要注意,如果想要在方法中调用 canvas
,需要提前声明全局变量,参考 2
import tkinter as tk
from tkinter import messagebox
from PIL import Image, ImageTk
import pickle
image = None
im = None
class LogIn:
def __init__(self):
self.root = tk.Tk()
self.root.title('Log in')
self.root.geometry('450x300+500+250')
self.interface()
def interface(self):
global image
global im
### create canvas
canvas = tk.Canvas(self.root, height=300, width=450)
image = Image.open("background.png")
im = ImageTk.PhotoImage(image)
bg = canvas.create_image(0, 0, anchor='nw', image=im)
canvas.pack(side='top')
### create labels and entries;
tk.Label(self.root, text='Username').place(x=80, y=100)
tk.Label(self.root, text='Password').place(x=80, y=150)
#
varUN = tk.StringVar()
varUN.set('xxx@gmail.com')
self.entryUN = tk.Entry(self.root, textvariable=varUN)
self.entryUN.place(x=160, y=100)
#
varPW = tk.StringVar()
self.entryPW = tk.Entry(self.root, textvariable=varPW, show='*')
self.entryPW.place(x=160, y=150)
btn_login = tk.Button(self.root, text='Log In', command=self.usr_login)
btn_login.place(x=150, y=230)
btn_sign_up = tk.Button(self.root, text='Sign Up', command=self.usr_sign_up)
btn_sign_up.place(x=250, y=230)
def usr_login(self):
'''
log in event bind to button Log in
if pickle file exists, load it; else, generate it;
:return:
'''
self.un = self.entryUN.get()
self.pw = self.entryPW.get()
try:
with open('usrs_info.pickle', 'rb') as usr_file:
usrs_info = pickle.load(usr_file)
except FileNotFoundError:
with open('usrs_info.pickle', 'wb') as usr_file:
usrs_info = {'admin': 'admin'}
pickle.dump(usrs_info, usr_file)
else:
if self.un in usrs_info:
if self.pw == usrs_info[self.un]:
tk.messagebox.showinfo(title='Welcome', message=f"'{self.un}' Log in successfully.")
else:
tk.messagebox.showinfo(title='Error', message=f"Please retry with your password '{self.pw}'.")
else:
is_sign_up = tk.messagebox.askyesno('Notice', 'Please register your personal account first.')
if is_sign_up:
self.usr_sign_up()
def usr_sign_up(self):
'''
sign up event bind to button sign up
:return:
'''
def sign():
# get data
np = newpw.get()
npf = newpw_confirm.get()
nn = newun.get()
# judge if data has already been registered;
with open('usrs_info.pickle', 'rb') as usr_file:
exist_usr_info = pickle.load(usr_file)
if np != npf:
tk.messagebox.showerror(title='Error', message='Confirm Your Password !')
elif nn in exist_usr_info:
tk.messagebox.showerror(title='Error', message='This username has been registered !')
else:
exist_usr_info[nn] = np
with open('usrs_info.pickle', 'wb') as usr_file:
# write username and password in user_info_pickle file in the format of dict
pickle.dump(exist_usr_info, usr_file)
tk.messagebox.showinfo(title='Welcome', message=f"Your register with '{nn}', '{np}' successfully.")
# destory top level window
win_signup.destroy()
win_signup = tk.Toplevel(self.root)
win_signup.title('Welcome to Register')
win_signup.geometry('450x300+500+250')
newun = tk.StringVar()
newun.set(self.un)
tk.Label(win_signup, text='Username').place(x=30, y=80)
entry_newun = tk.Entry(win_signup, textvariable=newun)
entry_newun.place(x=160, y=80)
newpw = tk.StringVar()
tk.Label(win_signup, text='Password').place(x=30, y=120)
entry_newpw = tk.Entry(win_signup, textvariable=newpw, show='*')
entry_newpw.place(x=160, y=120)
newpw_confirm = tk.StringVar()
tk.Label(win_signup, text='Confirm password').place(x=30, y=160)
entry_newpw_confirm = tk.Entry(win_signup, textvariable=newpw_confirm, show='*')
entry_newpw_confirm.place(x=160, y=160)
btn_signup_confirm = tk.Button(win_signup, text='Sign Up', command=sign)
btn_signup_confirm.place(x=200, y=220)
if __name__ == '__main__':
exLogIn = LogIn()
exLogIn.root.mainloop()
也许也可以参考这里 3,但是我没试成功。