python内置的GUI编程tkinter小巧灵活,本文以密码码器示例,所有注册的用户皆会被持久化
流程
用户登录/注册,成功则提示欢迎语,不正确或密码错误有相应警告
不存在帐户则提醒注册,并回调子页面注册,需要密码确认,注册已存在用户会被提醒
结构
两个window窗口,一个负责主界面引入了背景图,一个子负责注册账号密码,ui以tk为后缀名。event为tk的事件回调,store以pickle字典序列化存储类,usrs.pickle为持久化存储
entry
│ event.py
│ login_tk.py
│ sign_up_tk.py
│ store.py
│ usrs.pickle
│
├─.vscode
│ settings.json
│
├─img
│ coffee.png
│ java_classLoader.gif
│ web_spring.png
│ yms3mhzsf22.jpg
│
└─__pycache__
event.cpython-37.pyc
login.cpython-37.pyc
sign_up_tk.cpython-37.pyc
store.cpython-37.pyc
入口UI
login_tk.py
from tkinter import *
from tkinter import ttk
from event import login
from sign_up_tk import usr_sign_up
"""
定义界面
"""
# 1. 根实例
root = Tk()
root.title("Wellcome to Login")
root.geometry('400x350')
# 2.加载图片
canvas = Canvas(root, width=400, height=150, bg='green')
image_file = PhotoImage(file='img/coffee.png')
image = canvas.create_image(200, 0, anchor='n', image=image_file)
# 指定绘制方向
canvas.pack(side='top')
# 文本语录
ttk.Label(root, text='欢迎使用密码器', font=('Arial', 16)).pack()
# 3.用户静态文本
ttk.Label(root, text='用户:', font=('Arial', 14)).place(x=50, y=185)
ttk.Label(root, text='密码:', font=('Arial', 14)).place(x=50, y=215)
# 4.帐号输入变量
uname = StringVar()
uname.set('example@pardon110.com')
ttk.Entry(root, textvariable=uname, font=('Arial', 14)).place(x=120, y=185)
# 5.密码输入
pwd = StringVar()
# 6.文本变量绑定参数
ttk.Entry(root, textvariable=pwd, font=(
'Arial', 14), show='*').place(x=120, y=215)
# 7.事件回调使用变量
ttk.Button(root, text='登录', command=lambda: login(
uname.get(), pwd.get())).place(x=120, y=270)
# 8. 注册加子页面
ttk.Button(root, text='注册', command=lambda: usr_sign_up(
root)).place(x=250, y=270)
# 6.事件循环
root.mainloop()
注册UI
sign_up_tk.py
from tkinter import *
from tkinter import ttk
from event import sign_up_web
def usr_sign_up(root):
# 定义在主窗口上的次窗口
window_sign_up = Toplevel(root)
window_sign_up.geometry('300x200')
window_sign_up.title('注册')
# 用户名
uname = StringVar()
uname.set('example@pardon110.com')
ttk.Label(window_sign_up, text="用户名:").place(x=10, y=10)
ttk.Entry(window_sign_up, textvariable=uname).place(x=130, y=10)
# 密码
new_pwd = StringVar()
ttk.Label(window_sign_up, text='密码: ').place(x=10, y=50)
ttk.Entry(window_sign_up, textvariable=new_pwd,
show='*').place(x=130, y=50)
# 密码确认
new_pwd_confirm = StringVar()
ttk.Label(window_sign_up, text='重复密码: ').place(x=10, y=90)
ttk.Entry(window_sign_up, textvariable=new_pwd_confirm,
show='*').place(x=130, y=90)
# 确认注册
btn_comfirm_sign_up = ttk.Button(
window_sign_up, text='注册', command=lambda: sign_up_web(new_pwd.get(), new_pwd_confirm.get(), uname.get(), window_sign_up)).place(x=180, y=120)
事件回调
event.py
from tkinter import *
from tkinter import ttk
import tkinter.messagebox as msgbox
from store import Store
"""
回调事件模块
"""
def login(uname, pwd):
usrs_info = Store()._usrs
if uname in usrs_info:
if pwd == usrs_info[uname]:
msgbox.showinfo(
title="欢迎您", message='您还好吗? ' + uname)
else:
msgbox.showerror(
message='错误! 密码不正确, 请重试.')
else:
msgbox.askyesno(
'欢迎 '+uname, '你还没有注册,请先注册')
def sign_up_web(pwd,confirm,uname,window_sign_up):
db = Store()
if pwd != confirm:
print(pwd,confirm)
msgbox.showerror(
'错误', '两次输入的密码不一致!')
elif uname in db._usrs:
msgbox.showerror('警告', '该用户已经注册过!')
else:
# 注册新用户
db.add(uname,pwd).save()
msgbox.showinfo(
'欢迎'+uname, '您已经注册成功!')
# 销毁注册窗口
window_sign_up.destroy()
存储类
import pickle
"""
数据存储模块
"""
class Store:
def __init__(self, db="usrs.pickle"):
self._db = db
self._usrs = self._read()
def _read(self):
try:
# 反序列化对象
with open(self._db, 'rb') as f:
self._usrs = pickle.load(f)
except FileNotFoundError:
# 序列化对象
with open(self._db, 'wb') as f:
# 默认内置管理员
self._usrs = {'admin': '123456'}
# 持久化写入文件
pickle.dump(self._usrs, f)
return self._usrs
# 持久化
def save(self):
with open(self._db, 'wb') as f:
pickle.dump(self._usrs, f)
f.close()
# 添加新用户
def add(self, uname, pwd):
self._usrs[uname] = pwd
return self
def show(self):
print(self._usrs)
db = Store()
# db.add("zhansang","654321")
# db.save()
db.show()
其它
tk图像类只支持gif及png等有限图片,布局管理支持相对定位(pack自动计算),坐标系place,grid栅格系统