通訊錄管理程序設計與實現(Python實現)

通訊錄管理程序設計與實現(Python實現)

(代碼較長,不過功能清晰,讀者可視情況選取)
(圖片未能正常上傳,讀者可自行運行查看)
一、實驗目的與要求
實驗目的:鍛鍊面向對象編程與文件操作能力。
實驗要求:
1、熟悉VC++、Visual Studio c#或者Java編程環境。
2、運用面向對象知識對實驗題目進行分析和設計。
3、進行程序編寫和調試工作。

二、實驗內容
設計、實現一個具有通訊信息插入、修改、刪除、顯示、查詢和統計功能的通訊錄管理程序。程序設計功能及要求:
1、人數不定,數據使用文件存放。
2、記錄每位同學的學號、姓名、性別、工作單位、電話號碼和E-mail地址建立單獨的條目,存入數據文件。
3、可對記錄中的姓名和電話號碼等進行修改。
4、可增加或刪除記錄。
5、可顯示所有保存的記錄。
6、可以統計男女同學或總人數。
7、通過姓名、學號或電話號碼查詢到同學的條目。
8、在開始畫面加入簡單的菜單便於選擇功能。
9、儲存數據文件格式:
學號 姓名 性別 工作單位 電話號碼 E-mail
1 李四 …. …. ….
10、選做:加入文件加密系統,對儲存數據文件進行簡單的加密,要求通過直接打開儲存數據文件無法獲得其中的數據。但同時不影響程序對儲存數據文件的調用。

三、實驗設計
本次實驗同樣採用python編程環境,通訊錄人員信息採用字典類型,各項操作如添加、更改、刪除、搜索、統計、存入文件、讀取文件等都在字典的基礎上進行,以下爲此通訊錄管理系統包含的各項功能及其設計方法:
1)通訊錄人員文件(通訊錄.txt)的存入及讀取功能:
存入操作設計:因python無法直接將字典類型數據存入文件,故先將包含成員信息的字典轉化爲字符串(使用str()語句),後存入文件即可。
讀取操作設計:調用read()函數從文件中取出字符串,使用eval()函數將其轉化爲字典,再使用copy模塊中的deepcopy()函數拷貝給notes1,在note1上進行操作。
2)添加功能設計:
讀取文件,同時打開彈窗,由用戶輸入各項信息,點擊錄入按鈕。若學號已存在,則顯示“該學號已存在”,否則添加信息,並將所得信息寫入文件,此時顯示“錄入成功”。
3)刪除功能設計:
讀取文件,同時打開彈窗,爲防止用戶誤刪,採用姓名與學號同時鎖定對象進行刪除。由用戶輸入學號與姓名,點擊刪除按鈕。若學號不存在,則顯示“學生不存在!”,若姓名與學號不匹配,則顯示“學號與姓名不匹配!”,刪除操作採用pop()函數,最後將更改後的信息寫入文件,此時顯示“刪除成功!”。
4)修改功能設計:
讀取文件,同時打開彈窗,由用戶輸入學生學號,隨後選擇修改項目,在相應的文本框中輸入修改結果,點擊修改即可,最後將修改後的信息寫入文件,此時顯示“修改成功!”。
5)搜索功能設計:
此處提供三種可搜索項,用戶可通過學號、姓名、電話號進行搜索。首先讀取文件,同時打開彈窗,有用戶輸入檢索語句,點擊搜索按鈕,下方即顯示要搜索學生的所有信息。
6)統計功能設計:
此處提供三種統計功能,分別可統計人員總數、男生總數、女生總數。首先讀取文件,對文件中的數據進行依次遍歷匹配,匹配成功則計數器加一,最終在彈窗上顯示結果。
7)菜單設計:
將鼠標的觸發位置(二維參數)以post()方法傳遞給菜單,並將根窗體與鼠標右擊響應事件綁定,此時在電腦的上方則會出現菜單欄,添加各項功能語句,並分別與內部函數綁定,使用戶在點擊時會調出相應的彈窗進行操作。
8)顯示界面設計:
讀取文件,將信息依次遍歷並展現在所設畫布中,由於python中無法使畫布刷新或重新繪製,本人設立了旗幟flag,並引入全局變量t,使其在下方直接輸出信息展現給用戶,並有分割線方便用戶明確最新信息。

四、核心程序代碼

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#import pickle as p
import copy
# class person:
#     def write(self):
#       f = open('通訊錄.txt','wb+')
#       p.dump(person.notes,f)    #數據封裝
#       f.close()
#
#     def read(self):
#       file = '通訊錄.txt'
#       try:
#         f = open(file ,'rb+')
#         person.notes = p.load(f)    #從數據文件中讀取數據
#         f.close()
#       except:
#         f = open(file ,'w')
#         f.close()
#
# people = person()
# people.read()

#以下開始界面設計
# -*- coding:utf-8 -*-
from tkinter import *
HEIGHT = 5000
WIDTH = 5000
root = Tk()
root.title('可視化通訊錄管理系統')
root.geometry('900x800')
#畫布設計
# canvas = Canvas(root,height=HEIGHT,width=WIDTH,bg='#80c1ff')
# canvas.pack()

#此處爲各個標題的設計
lb1 = Label(root,text='學號',font=('黑體',16,'bold'))
lb1.place(relx=0.05,rely=0.02)
lb2 = Label(root,text='姓名',font=('黑體',16,'bold'))
lb2.place(relx=0.17,rely=0.02)
lb3 = Label(root,text='性別',font=('黑體',16,'bold'))
lb3.place(relx=0.29,rely=0.02)
lb4 = Label(root,text='工作單位',font=('黑體',16,'bold'))
lb4.place(relx=0.41,rely=0.02)
lb5 = Label(root,text='電話號碼',font=('黑體',16,'bold'))
lb5.place(relx=0.6,rely=0.02)
lb6 = Label(root,text='E-mail',font=('黑體',16,'bold'))
lb6.place(relx=0.8,rely=0.02)

#frame = Frame(root,bg='#80c1ff',bd=5)
flag = 1
t = 0
#顯示/刷新操作
def Show():
    fr = open("通訊錄.txt", 'r+')
    s1 = fr.read()
    if len(s1):
        note = eval(s1)  # 讀取的str轉化爲字典
        notes1 = copy.deepcopy(note)
    else:
        notes1={}
    fr.close()
    global t
    global flag
    if flag == 0:
        t = t + 1
    else:
        flag = 0
    for i in notes1.keys():
        label = Label(root, text='%s' % i, font=('宋體',14))
        label.place(relx=0.05, rely=0.06 + 0.03 * t)
        label = Label(root, text='%s' % notes1[i]['姓名'], font=('宋體', 14))
        label.place(relx=0.17, rely=0.06 + 0.03 * t)
        label = Label(root, text='%s' % notes1[i]['性別'], font=('宋體', 14))
        label.place(relx=0.29, rely=0.06 + 0.03 * t)
        label = Label(root, text='%s' % notes1[i]['工作單位'], font=('宋體', 14))
        label.place(relx=0.41, rely=0.06 + 0.03 * t)
        label = Label(root, text='%s' % notes1[i]['電話'], font=('宋體', 14))
        label.place(relx=0.6, rely=0.06 + 0.03 * t)
        label = Label(root, text='%s' % notes1[i]['E-mail'], font=('宋體', 14))
        label.place(relx=0.8, rely=0.06 + 0.03 * t)
        t = t+1
    label1 = Label(root,text='_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ' '_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _' '_ _ _ _以上爲最新紀錄',font=0.5)
    label1.place(relx=0.05,rely=0.06+0.03*t)

#子窗體設計
#插入 _add 子窗體
def newwind_add():
    winNew = Toplevel(root)
    winNew.geometry('320x240')
    winNew.title('插入')
    #各個錄入提示
    lb_1 = Label(winNew,text='請按以下要求依次輸入!')
    lb_1.place(relx=0.29,rely=0.05)
    lb_1_1 = Label(winNew,text='學號:')
    lb_1_1.place(relx=0.08,rely=0.18)
    lb_1_2 = Label(winNew, text='姓名:')
    lb_1_2.place(relx=0.08, rely=0.3)
    lb_1_3 = Label(winNew, text='性別:')
    lb_1_3.place(relx=0.08, rely=0.42)
    lb_1_4 = Label(winNew, text='工作單位:')
    lb_1_4.place(relx=0.08, rely=0.54)
    lb_1_5 = Label(winNew, text='電話號碼:')
    lb_1_5.place(relx=0.08, rely=0.66)
    lb_1_6 = Label(winNew, text='E-mail:')
    lb_1_6.place(relx=0.09, rely=0.78)
    #各個錄入條框
    e1 = StringVar()
    entry1 = Entry(winNew,textvariable=e1)
    entry1.place(relx=0.3,rely=0.18)
    e2 = StringVar()
    entry2 = Entry(winNew, textvariable=e2)
    entry2.place(relx=0.3, rely=0.3)
    e3 = StringVar()
    entry3 = Entry(winNew, textvariable=e3)
    entry3.place(relx=0.3, rely=0.42)
    e4 = StringVar()
    entry4 = Entry(winNew, textvariable=e4)
    entry4.place(relx=0.3, rely=0.54)
    e5 = StringVar()
    entry5 = Entry(winNew, textvariable=e5)
    entry5.place(relx=0.3, rely=0.66)
    e6 = StringVar()
    entry6 = Entry(winNew, textvariable=e6)
    entry6.place(relx=0.3, rely=0.78)
    def add():      #插入成員函數
        fr = open("通訊錄.txt",'r+')
        s1 = fr.read()
        if len(s1):
            note = eval(s1)   #讀取的str轉化爲字典
            notes1 = copy.deepcopy(note)
        else:
            notes1 = {}
        fr.close()
        id = e1.get()
        if id in notes1:
            lb_1_8 = Label(winNew, text='該學號已存在!')
            lb_1_8.place(relx=0.5, rely=0.9)
        else:
            name = e2.get()
            sex = e3.get()
            workspace = e4.get()
            telephone = e5.get()
            email = e6.get()
            label = {'姓名': name, '性別': sex, '工作單位': workspace, '電話': telephone, 'E-mail': email}
            notes1[id] = label
            lb_1_7 = Label(winNew, text='錄入成功!')
            lb_1_7.place(relx=0.5, rely=0.9)
            fw = open("通訊錄.txt","w+")
            fw.write(str(notes1))    #把字典轉化爲str
            fw.close()
    #錄入按鈕設計
    btAdd = Button(winNew,text='錄入',command=add)
    btAdd.place(relx=0.4,rely=0.9)
    #退出按鈕設計
    btClose=Button(winNew,text='退出',command=winNew.destroy)
    btClose.place(relx=0.88,rely=0.9)

#刪除學生子窗體
def newwind_del():
    fr = open("通訊錄.txt", 'r+')
    s1 = fr.read()
    if len(s1):
        note = eval(s1)  # 讀取的str轉化爲字典
        notes1 = copy.deepcopy(note)
    else:
        notes1={}
    fr.close()
    DelNew = Toplevel(root)
    DelNew.geometry('600x240')
    DelNew.title('刪除')
    lb_2_1 = Label(DelNew, text='請輸入要刪除學生學號:')
    lb_2_1.pack()
    e7 = StringVar()
    entry1 = Entry(DelNew,textvariable=e7)
    entry1.pack()
    lb_2_2 = Label(DelNew, text= '請輸入要刪除學生姓名:')
    lb_2_2.pack()
    e8 = StringVar()
    entry2 = Entry(DelNew,textvariable=e8)
    entry2.pack()
    def mydel():    #爲防止誤刪,此處用姓名與學號同時鎖定對象
        id = e7.get()
        name = e8.get()
        if id in notes1:
            if name == notes1[id]['姓名']:
                e = notes1.pop(id)
                lb_2_3 = Label(DelNew, text='刪除成功!')
                lb_2_3.pack()
                fw = open("通訊錄.txt", "w+")
                fw.write(str(notes1))  # 把字典轉化爲str
                fw.close()
            else:
                lb_2_3 = Label(DelNew, text='學號與姓名不匹配!')
                lb_2_3.pack()
        else:
            lb_2_3 = Label(DelNew, text='學生不存在!')
            lb_2_3.pack()
    btDel = Button(DelNew,text='刪除',command=mydel)
    btDel.pack()
    btClose = Button(DelNew,text='退出',command=DelNew.destroy)
    btClose.pack()


#修改學生子窗體
def newwind_modi():

    ModiNew = Toplevel(root)
    ModiNew.geometry('500x600')
    ModiNew.title('修改')
    lb_3_1 = Label(ModiNew, text='請輸入要修改學生學號:')
    lb_3_1.pack()
    e9 = StringVar()
    entry1 = Entry(ModiNew, textvariable=e9)
    entry1.pack()

    def modi_name():
        fr = open("通訊錄.txt", 'r+')
        s1 = fr.read()
        if len(s1):
            note = eval(s1)  # 讀取的str轉化爲字典
            notes1 = copy.deepcopy(note)
        else:
            notes1 = {}
        fr.close()
        id = e9.get()
        lb_3_3 = Label(ModiNew, text='要修改學生姓名爲:')
        lb_3_3.pack()
        e10 = StringVar()
        entry_1 = Entry(ModiNew, textvariable=e10)
        entry_1.pack()
        def name2():
            notes1[id]['姓名'] = e10.get()
            lb_3_8 = Label(ModiNew, text='修改成功!')
            lb_3_8.pack()
            fw = open("通訊錄.txt", "w")
            fw.write(str(notes1))  # 把字典轉化爲str
            fw.close()
        btCtl = Button(ModiNew, text='修改', command=name2)
        btCtl.pack()



    def modi_sex():
        fr = open("通訊錄.txt", 'r+')
        s1 = fr.read()
        if len(s1):
            note = eval(s1)  # 讀取的str轉化爲字典
            notes1 = copy.deepcopy(note)
        else:
            notes1 = {}
        fr.close()
        id = e9.get()
        lb_3_4 = Label(ModiNew, text='要修改學生性別爲:')
        lb_3_4.pack()
        e11 = StringVar()
        entry3 = Entry(ModiNew, textvariable=e11)
        entry3.pack()
        def sex2():
            notes1[id]['性別'] = e11.get()
            lb_3_8 = Label(ModiNew, text='修改成功!')
            lb_3_8.pack()
            fw = open("通訊錄.txt", "w")
            fw.write(str(notes1))  # 把字典轉化爲str
            fw.close()
        btCtl = Button(ModiNew, text='修改', command=sex2)
        btCtl.pack()


    def modi_workspace():
        fr = open("通訊錄.txt", 'r+')
        s1 = fr.read()
        if len(s1):
            note = eval(s1)  # 讀取的str轉化爲字典
            notes1 = copy.deepcopy(note)
        else:
            notes1 = {}
        fr.close()
        id = e9.get()
        lb_3_5 = Label(ModiNew, text='要修改學生工作單位爲:')
        lb_3_5.pack()
        e12 = StringVar()
        entry4 = Entry(ModiNew, textvariable=e12)
        entry4.pack()
        def workspace2():
            notes1[id]['工作單位'] = e12.get()
            lb_3_8 = Label(ModiNew, text='修改成功!')
            lb_3_8.pack()
            fw = open("通訊錄.txt", "w")
            fw.write(str(notes1))  # 把字典轉化爲str
            fw.close()
        btCtl = Button(ModiNew, text='修改', command=workspace2)
        btCtl.pack()

    def modi_telephone():
        fr = open("通訊錄.txt", 'r+')
        s1 = fr.read()
        if len(s1):
            note = eval(s1)  # 讀取的str轉化爲字典
            notes1 = copy.deepcopy(note)
        else:
            notes1 = {}
        fr.close()
        id = e9.get()
        lb_3_6 = Label(ModiNew, text='要修改學生電話號碼爲:')
        lb_3_6.pack()
        e13 = StringVar()
        entry5 = Entry(ModiNew, textvariable=e13)
        entry5.pack()
        def telephone2():
            notes1[id]['電話'] = e13.get()
            lb_3_8 = Label(ModiNew, text='修改成功!')
            lb_3_8.pack()
            fw = open("通訊錄.txt", "w")
            fw.write(str(notes1))  # 把字典轉化爲str
            fw.close()
        btCtl = Button(ModiNew, text='修改', command=telephone2)
        btCtl.pack()

    def modi_email():
        fr = open("通訊錄.txt", 'r+')
        s1 = fr.read()
        if len(s1):
            note = eval(s1)  # 讀取的str轉化爲字典
            notes1 = copy.deepcopy(note)
        else:
            notes1 = {}
        fr.close()
        id = e9.get()
        lb_3_7 = Label(ModiNew, text='要修改學生E-mail爲:')
        lb_3_7.pack()
        e14 = StringVar()
        entry6 = Entry(ModiNew, textvariable=e14)
        entry6.pack()
        def email2():
            notes1[id]['E-mail'] = e14.get()
            lb_3_8 = Label(ModiNew, text='修改成功!')
            lb_3_8.pack()
            fw = open("通訊錄.txt", "w")
            fw.write(str(notes1))  # 把字典轉化爲str
            fw.close()
        btCtl = Button(ModiNew, text='修改', command=email2)
        btCtl.pack()

    def modi_all():
        fr = open("通訊錄.txt", 'r+')
        s1 = fr.read()
        if len(s1):
            note = eval(s1)  # 讀取的str轉化爲字典
            notes1 = copy.deepcopy(note)
        else:
            notes1 = {}
        fr.close()
        id = e9.get()
        if id in notes1:
            lb_3_2 = Label(ModiNew, text='要修改學生項目爲')
            lb_3_2.pack()
            btChoose1 = Button(ModiNew, text='姓名', command=modi_name)
            btChoose1.pack(side=LEFT,anchor=NW,ipadx=0.2)
            btChoose2 = Button(ModiNew, text='性別', command=modi_sex)
            btChoose2.pack(side=LEFT,anchor=NW,ipadx=0.2)
            btChoose3 = Button(ModiNew, text='工作單位', command=modi_workspace)
            btChoose3.pack(side=LEFT,anchor=NW,ipadx=0.2)
            btChoose4 = Button(ModiNew, text='電話號碼', command=modi_telephone)
            btChoose4.pack(side=LEFT,anchor=NW,ipadx=0.2)
            btChoose5 = Button(ModiNew, text='E-mail', command=modi_email)
            btChoose5.pack(side=LEFT,anchor=NW,ipadx=0.2)
        else:
            lb_3_9 = Label(ModiNew, text='學生不存在!')
            lb_3_9.pack()
    btCtl = Button(ModiNew, text='修改', command=modi_all)
    btCtl.pack()
    btclose = Button(ModiNew, text='退出', command=ModiNew.destroy)
    btclose.place(relx=0.89,rely=0.89)

#搜索操作

#按學號查找子窗體:
def newwind_search1():
    fr = open("通訊錄.txt", 'r+')
    s1 = fr.read()
    if len(s1):
        note = eval(s1)  # 讀取的str轉化爲字典
        notes1 = copy.deepcopy(note)
    else:
        notes1 = {}
    fr.close()
    Se1New = Toplevel(root)
    Se1New.geometry('600x400')
    Se1New.title('按學號查找')
    lb_4_1 = Label(Se1New,text='請輸入要查找學生學號:')
    lb_4_1.pack()
    e15 = StringVar()
    entry1 = Entry(Se1New,textvariable=e15)
    entry1.pack()
    def search1():
        id=e15.get()
        if id in notes1:
            lb_4_2 = Label(Se1New,text = '學號 %s 的姓名是 %s , 性別是 %s , 工作單位是 %s , 電話是 %s , E-mail是 %s'
                      % (id, notes1[id]['姓名'], notes1[id]['性別'], notes1[id]['工作單位'],
                         notes1[id]['電話'], notes1[id]['E-mail']))
            lb_4_2.pack()
        else:
            lb_4_3 = Label(Se1New,text='該學生不存在!')
            lb_4_3.pack()
    btse1 = Button(Se1New,text='搜索',command=search1)
    btse1.pack()

#按姓名查找子窗體:
def newwind_search2():
    fr = open("通訊錄.txt", 'r+')
    s1 = fr.read()
    if len(s1):
        note = eval(s1)  # 讀取的str轉化爲字典
        notes1 = copy.deepcopy(note)
    else:
        notes1 = {}
    fr.close()
    Se2New = Toplevel(root)
    Se2New.geometry('600x400')
    Se2New.title('按姓名查找')
    lb_5_1 = Label(Se2New,text='請輸入要查找學生姓名:')
    lb_5_1.pack()
    e16 = StringVar()
    entry1 = Entry(Se2New,textvariable=e16)
    entry1.pack()
    def search2():
        name = e16.get()
        t = 0   #計數器
        for i in notes1.keys():
            t = t+1
            if notes1[i]['姓名'] == name:
                lb_5_2 = Label(Se2New,text='學號 %s 的姓名是 %s , 性別是 %s , 工作單位是 %s , 電話是 %s , E-mail是 %s'
                      % (i, notes1[i]['姓名'], notes1[i]['性別'], notes1[i]['工作單位'],
                         notes1[i]['電話'], notes1[i]['E-mail']))
                lb_5_2.pack()
                t = 0   #輸出則計數器清零
        if t == len(notes1):
            lb_5_3 = Label(Se2New,text='該學生不存在!')
            lb_5_3.pack()
    btse2 = Button(Se2New, text='搜索', command=search2)
    btse2.pack()

#按電話號碼查找子窗體:
def newwind_search3():
    fr = open("通訊錄.txt", 'r+')
    s1 = fr.read()
    if len(s1):
        note = eval(s1)  # 讀取的str轉化爲字典
        notes1 = copy.deepcopy(note)
    else:
        notes1 = {}
    fr.close()
    Se3New = Toplevel(root)
    Se3New.geometry('600x400')
    Se3New.title('按電話號碼查找')
    lb_6_1 = Label(Se3New,text='請輸入要查找學生電話號:')
    lb_6_1.pack()
    e17 = StringVar()
    entry1 = Entry(Se3New,textvariable=e17)
    entry1.pack()
    def search3():
        telephone = e17.get()
        t = 0
        for i in notes1.keys():
            t = t+1
            if notes1[i]['電話']==telephone:
                lb_6_2 = Label(Se3New,text='學號 %s 的姓名是 %s , 性別是 %s , 工作單位是 %s , 電話是 %s , E-mail是 %s'
                      % (i, notes1[i]['姓名'], notes1[i]['性別'], notes1[i]['工作單位'],
                         notes1[i]['電話'], notes1[i]['E-mail']))
                lb_6_2.pack()
                t = 0
            if t==len(notes1):
                lb_6_3 = Label(Se3New,text='該學生已存在!')
                lb_6_3.pack()
    btse3 = Button(Se3New,text='搜索',command=search3)
    btse3.pack()

#統計操作

#統計總人數
def newwind_Sp():
    fr = open("通訊錄.txt", 'r+')
    s1 = fr.read()
    if len(s1):
        note = eval(s1)  # 讀取的str轉化爲字典
        notes1 = copy.deepcopy(note)
    else:
        notes1 = {}
    fr.close()
    SpNew = Toplevel(root)
    SpNew.geometry('320x180')
    SpNew.title('總人數')
    sum = len(notes1)
    lb_7 = Label(SpNew,text='學生總數爲 %d '%sum,font=('黑體',16,'bold') )
    lb_7.pack()
    btClose = Button(SpNew, text='退出', command=SpNew.destroy)
    btClose.place(relx=0.7, rely=0.7)

#統計男生人數
def newwind_Sman():
    fr = open("通訊錄.txt", 'r+')
    s1 = fr.read()
    if len(s1):
        note = eval(s1)  # 讀取的str轉化爲字典
        notes1 = copy.deepcopy(note)
    else:
        notes1 = {}
    fr.close()
    SmanNew = Toplevel(root)
    SmanNew.geometry('320x180')
    SmanNew.title('男生總數')
    t = 0
    for i in notes1.keys():
        if notes1[i]['性別']=='男':
            t = t+1
    lb_8 = Label(SmanNew,text='男生總數爲 %d '%t,font=('黑體',16,'bold') )
    lb_8.pack()
    btClose = Button(SmanNew, text='退出', command=SmanNew.destroy)
    btClose.place(relx=0.7, rely=0.7)
#統計女生人數
def newwind_Sfemale():
    fr = open("通訊錄.txt", 'r+')
    s1 = fr.read()
    if len(s1):
        note = eval(s1)  # 讀取的str轉化爲字典
        notes1 = copy.deepcopy(note)
    else:
        notes1 = {}
    fr.close()
    SfemaleNew = Toplevel(root)
    SfemaleNew.geometry('320x180')
    SfemaleNew.title('女生總數')
    t = 0
    for i in notes1.keys():
        if notes1[i]['性別']=='女':
            t = t+1
    lb_9 = Label(SfemaleNew, text='女生總數爲 %d ' % t,font=('黑體',16,'bold'))
    lb_9.pack()
    btClose = Button(SfemaleNew, text='退出', command=SfemaleNew.destroy)
    btClose.place(relx=0.7, rely=0.7)

#菜單設計
mainmenu = Menu(root)
menuFile = Menu(mainmenu)   #菜單分組 menuFile
mainmenu.add_cascade(label="通訊錄",menu=menuFile)
menuFile.add_command(label="顯示/刷新",command=Show)
menuFile.add_separator()    #分割線
menuFile.add_command(label="退出",command=root.destroy)

menuEdit = Menu(mainmenu)   #菜單分組 menuEdit
mainmenu.add_cascade(label="編輯",menu=menuEdit)
menuEdit.add_command(label="插入",command=newwind_add)
menuEdit.add_command(label="修改",command=newwind_modi)
menuEdit.add_command(label="刪除",command=newwind_del)

menuSearch = Menu(mainmenu) #菜單分組 menuSearch
mainmenu.add_cascade(label="查詢",menu=menuSearch)
menuSearch.add_command(label="按學號查找",command=newwind_search1)
menuSearch.add_command(label="按姓名查找",command=newwind_search2)
menuSearch.add_command(label="按電話查找",command=newwind_search3)

menuCount = Menu(mainmenu)  #菜單分組 menuCount
mainmenu.add_cascade(label="統計",menu=menuCount)
menuCount.add_command(label="學生總數",command=newwind_Sp)
menuCount.add_command(label="男生總數",command=newwind_Sman)
menuCount.add_command(label="女生總數",command=newwind_Sfemale)

#將鼠標的觸發位置event.x_root 和 event.y_root以post()方法傳給菜單
def popupmenu(event):
    mainmenu.post(event.x_root, event.y_root)
root.config(menu=mainmenu)
root.bind('<Button-3>',popupmenu) # 根窗體綁定鼠標右擊響應事件

root.mainloop()

五、實驗結果
1 界面展示
1)菜單界面及主顯示界面:

2)菜單中各選項內部功能:

3)插入操作窗口:

4)刪除操作窗口:

5)修改操作窗口:

6)按學號查找窗口:

7)按姓名查找窗口:

8)按電話號碼查找窗口:

9)統計總人數窗口:

10)統計男生總數窗口:

11)統計女生總數窗口:

2 各項功能操作展示
1)插入操作
此處共錄入三名學生如下:

畫布中顯示:

文件中顯示:

2)修改操作
此處將0003號學生信息進行修改,如下:

畫布中顯示:

文件中顯示:

3)刪除操作:
此處刪除0001號同學,如下:

畫布中顯示:

文件中顯示:

4)按學號查找:
此處查找0001號學生,因上一步已被刪除,故應顯示“該學生不存在”,操作如下:

另查找0002號學生,則顯示其所有信息,操作如下:

5)按姓名查找:
此處查找劉伊同學,則顯示其全部信息,操作如下:

6)按電話查找:
此處搜索122345,應查找到趙可,並輸出其全部信息,操作如下:

7)統計學生總人數:
顯示彈窗如下:

8)統計男生總人數:
顯示彈窗如下:

9)統計女生總人數:
顯示彈窗如下:

六、實驗總結
本實驗設計過程可以說是歷經各種坎坷,代碼量也十分巨大,共578行(含註釋)。
其中文件的存入及讀取操作設計部分,由於本人採用字典操作,故需要特別轉化進行存入與讀取,涉及到的算法經過不斷調試最終成功通過,同時在代碼開頭部分,本人採用pickle模塊,可對存入文件中的數據進行封裝(使用dump()函數),好處在於可以將數據存取爲只能用python編程環境讀取的類型(讀取時採用load()函數),可起到加密的作用。
在可視化設計過程中,考慮了多項因素,包括按鈕,文本框的佈局、函數的內部傳遞參數、特殊情況的程序處理、菜單的設計等等。菜單設計過程中,通過查找大量的博客、閱讀他人代碼學習到傳遞位置參量的設計方法並在此次設計實驗中得到了應用與體現。而在界面設計過程中,由於python中可調佈局的函數(pack(),grid(),place())僅有三種,同時函數的使用需要輸入不同的參數,控制其顯示位置,故在此過程中,本人爲使得到的界面儘量精美,經過了一個漫長的佈局過程。不過仍有不足的地方無法調試,例如修改彈窗中各個按鈕及文本框的佈局中仍有一些空白部分無法填充。
總體過程雖有一些坎坷,好在盡力都解決了已知的問題。此次設計實驗充分鍛鍊了自己調用tkinter模塊設計佈局的能力,有一個顯著的提升,同時也發現,用python環境做可視化設計確實略有一些困難,其內部的一些模塊函數還需要持續更新,設計佈局函數方面不夠人性化,也不夠便捷。不過本人爲充分鍛鍊自己的python編程能力,披荊斬棘,也算取得勝利。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章