前言
前面我們學(xué)習(xí)了Python GUI 圖像化界面Tkinter的基礎(chǔ)知識(shí),為了檢測(cè)我們的學(xué)習(xí)成果吊输,學(xué)以致用惩歉。我們從今天開(kāi)始做一個(gè)綜合Tkinter案例--基于Tkinter的學(xué)生信息管理系統(tǒng),一方面熟悉Tkinter項(xiàng)目的開(kāi)發(fā)嗅辣,另一方面可以把我們前面的《Python基礎(chǔ)學(xué)習(xí)筆記》的知識(shí)綜合在一起。
基礎(chǔ)功能介紹
說(shuō)明:
由于我們尚未學(xué)習(xí)數(shù)據(jù)庫(kù)的內(nèi)容挠说,所以我們這個(gè)應(yīng)用程序開(kāi)發(fā)的過(guò)程中澡谭,暫時(shí)通過(guò)文件的讀寫方式來(lái)存儲(chǔ)數(shù)據(jù)。等到后面我們介紹了關(guān)系數(shù)據(jù)庫(kù)的知識(shí)损俭,整個(gè)項(xiàng)目對(duì)接到數(shù)據(jù)庫(kù)中也是很方便的蛙奖。
感興趣的小伙伴們,可以直接私信我免費(fèi)獲取項(xiàng)目使用到的素材和源碼杆兵,我們一起手把手搭建這個(gè)項(xiàng)目雁仲!
1.登錄功能
本項(xiàng)目支持用戶名和密碼的驗(yàn)證登錄,支持密碼輸入三次自動(dòng)鎖定等功能琐脏;
2. 主窗體
(1)顯示當(dāng)前登錄用戶名攒砖、登錄時(shí)間
(2)支持添加學(xué)生信息缸兔、修改學(xué)生信息、刪除學(xué)生信息吹艇、更改當(dāng)前賬號(hào)密碼
(2)支持多條件查詢學(xué)生信息
這里我們查詢所有學(xué)號(hào)以31901開(kāi)頭的學(xué)生惰蜜,在這些學(xué)生中再次篩選手機(jī)號(hào)碼中有138號(hào)段的學(xué)生。
3. 添加并查看學(xué)生信息
點(diǎn)擊添加按鈕可以添加學(xué)生信息受神,保存后抛猖,可查看明細(xì)信息。同時(shí)也支持修改與刪除鼻听。
4. 更改當(dāng)前賬戶的密碼
支持更改當(dāng)前賬戶密碼财著,同時(shí)具備密碼校驗(yàn)功能。
好啦精算,從現(xiàn)在開(kāi)始正式進(jìn)入項(xiàng)目的開(kāi)發(fā)吧,今天我們要做的內(nèi)容是登錄界面框架GUI的設(shè)計(jì)與功能實(shí)現(xiàn)碎连!
一灰羽、 登錄界面的實(shí)現(xiàn)
from tkinter import *
from tkinter.ttk import *
import os
class LoginWindow(Tk):
"""
創(chuàng)建登錄窗體的GUI界面已經(jīng)登錄的方法
"""
def __init__(self):
super().__init__() # 先執(zhí)行tk這個(gè)類的初始化
self.title("登錄界面")
# self.geometry("620x420")
self.resizable(0,0) # 窗體大小不允許變,兩個(gè)參數(shù)分別代表x軸和y軸
self.iconbitmap("."+os.sep+"img"+os.sep+"student.ico")
# self["bg"] = "royalblue"
# 加載窗體
self.setup_UI()
def setup_UI(self):
# ttk中控件使用style對(duì)象設(shè)定
self.Style01 = Style()
self.Style01.configure("user.TLabel",font = ("華文黑體",20,"bold"),foreground = "royalblue")
self.Style01.configure("TEntry",font = ("華文黑體",20,"bold"))
self.Style01.configure("TButton",font = ("華文黑體",20,"bold"),foreground = "royalblue")
# 創(chuàng)建一個(gè)Label標(biāo)簽展示圖片
self.Login_image = PhotoImage(file = "."+os.sep+"img"+os.sep+"logingui.png")
self.Label_image = Label(self,image = self.Login_image)
self.Label_image.pack(padx = 10,pady = 10)
# 創(chuàng)建一個(gè)Label標(biāo)簽 + Entry --- 用戶名
self.Label_user = Label(self,text = "用戶名:", style = "user.TLabel")
self.Label_user.pack(side = LEFT,padx = 10,pady = 10)
self.Entry_user = Entry(self,width = 12)
self.Entry_user.pack(side = LEFT,padx = 10,pady = 10)
# 創(chuàng)建一個(gè)Label標(biāo)簽 + Entry --- 密碼
self.Label_password = Label(self, text = "密碼:", style = "user.TLabel")
self.Label_password.pack(side = LEFT,padx = 10,pady = 10)
self.Entry_password = Entry(self, width=12,show = "*")
self.Entry_password.pack(side = LEFT,padx = 10,pady = 10)
# 創(chuàng)建一個(gè)按鈕 --- 登錄
self.Button_login = Button(self,text = "登錄",width = 4)
self.Button_login.pack(side = LEFT,padx = 20,pady = 10)
if __name__ == '__main__':
this_login = LoginWindow()
this_login.mainloop()
效果:
二鱼辙、讀取文件
讀取文本中的的用戶信息廉嚼,記得先判斷文件路徑是否存在,如果文件不存在就彈一個(gè)彈窗倒戏,如果存在繼續(xù)做異常處理是否能打開(kāi)文件讀取內(nèi)容怠噪。按行讀取,每一行再分割杜跷,分割后存儲(chǔ)到user_list[]用戶列表中傍念。
def load_file_info(self):
if not os.path.exists(self.file_path):
showinfo("系統(tǒng)消息","提供的文件名不存在!")
else:
try:
with open(file = self.file_path,mode = "r") as fd:
# 一次讀一行
current_line = fd.readline()
while current_line:
temp_list = current_line.split(",") # 長(zhǎng)字符串分割層三個(gè)
self.user_list.append(temp_list)
# 讀取下一行,讀完了循環(huán)就結(jié)束了
current_line = fd.readline()
except:
showinfo("系統(tǒng)消息","文件讀取出現(xiàn)異常葛闷!")
存儲(chǔ)用戶信息的文本文件路徑作為全局變量存儲(chǔ)憋槐,這樣后面還會(huì)調(diào)用的時(shí)候就不需要重寫方法,其它方法調(diào)用也會(huì)方便一些淑趾。
我們?cè)诔跏蓟椒ㄖ卸x全局變量:
# 定義變量(定義全局變量阳仔,后面的函數(shù)都能訪問(wèn)到)
self.file_path = "/Users/yushengtan/Desktop/Demo/Studentmgr/User.txt" # 文件路勁
self.user_list = [] # 存儲(chǔ)用戶信息
# 自動(dòng)執(zhí)行文件中賬號(hào)的加載
self.load_file_info()
三、獲取輸入賬號(hào)的信息
需要在控件里捆綁變量扣泊,再定義一個(gè)login()方法近范,通過(guò)控件變量.get()方法獲取輸入的值,再給登錄按鈕添加一個(gè)command事件
def login(self):
# 獲取用戶的用戶名和密碼
user = self.var_user.get()
password = self.var_password.get()
showinfo(message="用戶名:"+user+"密碼:"+password) # 暫時(shí)用彈窗測(cè)試一下內(nèi)容獲取是否正常
四、實(shí)現(xiàn)基本的身份驗(yàn)證
關(guān)于登錄驗(yàn)證延蟹,要求如下:
(1)如果用戶名不對(duì)评矩,提示:用戶名不存在
(2)如果密碼不對(duì),提示:密碼錯(cuò)誤
(3)如果密碼連續(xù)輸錯(cuò)三次阱飘,提示:賬號(hào)已鎖定稚照,請(qǐng)聯(lián)系管理員
(4)如果用戶名和密碼正確,加載主窗體
實(shí)現(xiàn)基本身份驗(yàn)證的框架:
# 實(shí)現(xiàn)身份驗(yàn)證,遍歷用戶信息列表
for index in range(len(self.user_list)):
# 用戶名是否正確
if user.strip().lower() == str(self.user_list[index][0]).strip().lower():
# 判斷賬號(hào)是否被禁用
if "0" in str(self.user_list[index][2]).strip().lower():
showinfo("系統(tǒng)消息", "賬號(hào)已禁用,請(qǐng)聯(lián)系管理員")
break
# 密碼是否正確
if password != str(self.user_list[index][1]).strip().lower():
showinfo("系統(tǒng)消息", "輸入的密碼錯(cuò)誤")
# 判斷成功后整個(gè)循環(huán)退出果录,不要執(zhí)行后面的判斷用戶名不存在的語(yǔ)句了
break
else:
showinfo("系統(tǒng)消息", "登錄成功上枕!")
break
# 如果校驗(yàn)到最后都沒(méi)有相同的用戶名,則用戶名不存在
if index == len(self.user_list) - 1:
showinfo("系統(tǒng)消息","輸入的用戶名不存在")
五、密碼輸錯(cuò)三次鎖定賬號(hào)
首先我們需要使用全局變量記錄密碼輸錯(cuò)多少次弱恒,
def login(self):
# 獲取用戶的用戶名和密碼
user = self.var_user.get()
password = self.var_password.get()
# 實(shí)現(xiàn)身份驗(yàn)證辨萍,遍歷用戶信息列表
for index in range(len(self.user_list)):
# 用戶名是否正確
if user.strip().lower() == str(self.user_list[index][0]).strip().lower():
# 判斷賬號(hào)是否被禁用
if "0" in str(self.user_list[index][2]).strip().lower():
showinfo("系統(tǒng)消息", "賬號(hào)已禁用,請(qǐng)聯(lián)系管理員")
break
# 密碼是否正確
if password != str(self.user_list[index][1]).strip().lower():
self.var_password_error_times += 1
# 判讀錯(cuò)誤是否到三次
if self.var_password_error_times >= 3:
showinfo("系統(tǒng)消息","密碼錯(cuò)誤已達(dá)三次,賬號(hào)已鎖定返弹!")
# 改變狀態(tài)
self.user_list[index][2] = "0\n"
# 信息寫入到文件
self.write_file_info()
else:
showinfo("系統(tǒng)消息", "輸入的密碼錯(cuò)誤")
# 判斷成功后整個(gè)循環(huán)退出锈玉,不要執(zhí)行后面的判斷用戶名不存在的語(yǔ)句了
break
else:
# 如果在三次之內(nèi)輸入正確了,把錯(cuò)誤次數(shù)歸零
self.var_password_error_times = 0
showinfo("系統(tǒng)消息", "登錄成功义起!")
break
# 如果校驗(yàn)到最后都沒(méi)有相同的用戶名,則用戶名不存在
if index == len(self.user_list) - 1:
showinfo("系統(tǒng)消息","輸入的用戶名不存在")
將用戶信息寫入文件:
def write_file_info(self):
# 1.清空文件拉背;2.寫入
try:
with open(file = self.file_path,mode="w") as fd:
fd.write("")
with open(file = self.file_path,mode="a") as fd:
for item in self.user_list:
fd.write(",".join(item))
except:
showinfo("系統(tǒng)消息","寫入文件出現(xiàn)異常")
六、完成主窗體的加載
創(chuàng)建一個(gè)主窗體maingui.py
from tkinter import *
from tkinter.ttk import *
class MainWindow(Tk):
def __init__(self):
super().__init__()
self.title("主窗體")
self.geometry("900x640+180+80")
self.resizable(0,0)
self["bg"]="royalblue"
在登錄窗體中再定義一個(gè)登錄主窗體跳轉(zhuǎn)方法:
def load_main(self):
# 關(guān)閉當(dāng)前窗體
self.destroy()
# 加載新窗體
if __name__ == '__main__':
main_window = maingui.MainWindow()
在登錄方法login()中默终,用戶密碼驗(yàn)證成功后椅棺,調(diào)用跳轉(zhuǎn)主窗體的方法即可;
至此齐蔽,我們登錄窗體就已經(jīng)搭建完成了两疚!
最后
本節(jié)我們先整體介紹了一下該項(xiàng)目的主要功能,然后就開(kāi)始了項(xiàng)目的第一步:登錄窗體的實(shí)現(xiàn)含滴,實(shí)現(xiàn)了用戶名和密碼的校驗(yàn)功能诱渤,完成了登錄窗體我們點(diǎn)擊登錄按鈕希望能加載主窗體界面,這該如何實(shí)現(xiàn)呢谈况?下一節(jié)勺美,我們將介紹主窗體的界面的搭建和功能的實(shí)現(xiàn)。