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('[email protected]') 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('[email protected]') 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栅格系统