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