摘 要
通讯录是每一款手机必备的一个应用,它拥有的功能非常简单,大致有添加联系人,修改联系人信息,删除联系人,查找联系人等功能,本次课程设计我使用python和python中丰富的第三方库。在通讯录的设计中,我主要采用了python的tkinter模块和os模块,实现了代码的可视化。我运用python的tkinter模块实现通讯录的窗口,按钮,弹出提示窗口,再多次运用了函数和类的使用,其中各模块均使用函数进行封装,以增强复用性,这些模块给予了通讯录的输入,输出,保存,查找,删除等一些功能,使得通讯录有了实质的作用。最终完成了通讯录。
关键词:通讯录;python;tkinter模块;可视化
目 录
1.概述
1.1设计目的
1.2需求分析
2. 总体设计
2.1 程序总体设计思想
2.2 程序设计总体框架
3.详细设计
3.1 功能模块
3.2 查找联系人
4.算法描述与实现
4.1通讯录界面
4.2添加联系人
4.3 保存联系人
4.4双击联系人条目
4.5右键菜单
4.6 删除所有联系人
4.7搜索联系人
总结
参考文献
本课程设计是python语言学习中很重要的实践性环节之一,是在学习完python课程后进行一次全面的综合练习旨在巩固和加深我们对python语言的基本知识的理解和掌握,掌握python语言编程和程序调试的基本功能,利用python语言进行基本的软件设计,掌握书写程序设计说明文档的能力,提高运用python语言解决实际问题的能力。
通讯录要实现最基本的功能,包括新建联系人,查找信息,删除信息,修改信息,退出系统,为此需要首先定义记录项的格式,其基本属性包括姓名、电话、地址、邮箱。
通讯录管理系统主要包括以下功能:
个人通讯录的功能模块有:
(1)提供通讯录界面,操作简单,易学。
(2)添加:可以添加通讯录记录,依次输入姓名、电话号码、工作地址、电子邮箱地址,在程序设计中将姓名,电话设置为必须输入,工作地址和电子邮箱为可选择输入。
(3)显示:设计一个空白框架,可以显示已经保存的联系人基本信息。
查询:可以用姓名(可以只输入部分姓名即可查询),电话号码(前几位电话号码即可查询)。
(4)修改:先进行查询,在查找到的界面,找到想要修改的联系人,鼠标右键点击即弹出修改联系人框架,可以对其中任意一条进行修改。
删除:本程序包含两种删除方式,第一条即删除所有联系人,类似于重置通讯录信息,另一种是在显示框架内鼠标右键弹出删除联系人。
2.2 程序设计总体框架
个人通讯录管理系统设计的总体框架如图2.1所示:
图2.1个人通讯录管理系统设计的总体流程图
3.详细设计
(1)根据上述的功能,可以设计出系统的总体模块,如图3.1所示:
图3.1通讯录管理系统功能模块示意图
图3.2添加联系人图
查找联系人可以分为两种方式,一是在主界面的显示框中直接搜索,二是在搜索框架中直接搜索,第二种主要采用的方式是文件的读写功能。如图3.3所示:
图3.3查找联系人图
这两种方法第一类使用的次数较多,使用鼠标进行简单的操作就可以完成自己想做的事情,第二种方法适用于联系人较多,无法快速直观的找到所需的联系人,两种方法配合使用,使通讯录的功能更加完整。
4.算法描述与实现
通讯录界面是整个应用的核心,要对其中的按钮大小,放置的位置进行计算,要做到一目了然,用户用起来更加方便。其界面如图4.1所示:
图4.1通讯录界面图
代码实现如下:
from tkinter import *
from tkinter import font
from tkinter import messagebox
from os import path
from os import remove
class PopupWindow(object):
# 初始化构造及添加组件到弹出框
def __init__(self, master, main_window, title, contact=None):
self.main_window = main_window
top = self.top = Toplevel(master)
top.title(title)
top.resizable(False, False)
w = 280
h = 320
top.geometry('%dx%d+%d+%d' % (w, h, (ws - w) / 2, (hs - h) / 2))
top.bind('
m_font = font.Font(size=16)
l = Label(top, text="姓名:", font=m_font)
l.pack(side=TOP, pady=5)
self.e1 = Entry(top)
self.e1.pack(side=TOP, padx=16, ipady=3, fill=X)
self.e1.focus()
if contact is not None:
self.e1.insert(0, contact.name)
l2 = Label(top, text="电话号码:", font=m_font)
l2.pack(side=TOP, pady=5)
self.e2 = Entry(top)
self.e2.pack(side=TOP, padx=16, ipady=3, fill=X)
if contact is not None:
self.e2.insert(0, contact.phone_number)
l2 = Label(top, text="工作单位:", font=m_font)
l2.pack(side=TOP, pady=5)
self.e3 = Entry(top)
self.e3.pack(side=TOP, padx=16, ipady=3, fill=X)
if contact is not None:
self.e3.insert(0, contact.work_place)
l2 = Label(top, text="E-mail地址:", font=m_font)
l2.pack(side=TOP, pady=5)
self.e4 = Entry(top)
self.e4.pack(side=TOP, padx=16, ipady=3, fill=X)
if contact is not None:
self.e4.insert(0, contact.e_mail)
if contact is None:
b2 = Button(top, text='添加', width=12, command=lambda: self.add_click(None))
self.e4.bind('
else:
b2 = Button(top, text='编辑', width=12, command=lambda: self.edit_click(None))
self.e4.bind('
b2.pack(side=LEFT, pady=10, padx=20)
b3 = Button(top, text='取消', width=12, command=lambda: top.destroy())
b3.pack(side=RIGHT, pady=10, padx=20)
top.grab_set()
在通讯录界面中能直观的看出通讯录具有的功能,可以进行添加联系人,删除联系人,保存联系人,查找联系人,和显示已经保存的联系人。
其中先是导入python的tkinter模块,可以实现一个基本框架,后续在导入tkinter的messagebox模块,可以在基本框架中添加按钮,在添加主界面类中,先是对整个框架的大小进行确定,再对其中的按钮大小进行调整,在保证可以装下这些按钮的同时又保持界面的美观和整洁。
这一步其实也是对python的tkinter模块的使用进一步的练习,并且对其模块中的各类函数进一步的掌握。
添加联系人是基本功能之一,点击添加联系人后会弹出添加框,其中包括姓名,电话号码,工作单位,E-mail地址填写信息。如图4.2所示:
4.2添加联系人图
添加联系人弹窗代码如下所示:
# 添加、编辑联系人弹窗
def popup(self, title, contact=None):
self.cancel_search(None)
self.w = PopupWindow(self.root, self, title, contact)
self.addBtn["state"] = "disabled"
self.root.wait_window(self.w.top)
self.addBtn["state"] = "normal"
其中姓名电话号码是必填写,缺少任何一个都不能保存,并且会弹出提示(编辑联系人信息也一样),如图4.3所示:
图4.3弹出提示框
代码实现,如下所示:
def edit_click(self, event):
e1_name = self.e1.get()
if not e1_name:
messagebox.showinfo("出错了", '名字不能为空!')
return
e2_name = self.e2.get()
if not e2_name:
messagebox.showinfo("出错了", '电话号码不能为空!')
return
e3_name = self.e3.get()
e4_name = self.e4.get()
self.main_window.edit_value(e1_name, e2_name, e3_name, e4_name)
self.top.destroy()
# 点击添加联系人按钮
def add_click(self, event):
e1_name = self.e1.get()
if not e1_name:
messagebox.showinfo("出错了", '名字不能为空!')
return
e2_name = self.e2.get()
if not e2_name:
messagebox.showinfo("出错了", '电话号码不能为空!')
return
e3_name = self.e3.get()
e4_name = self.e4.get()
self.main_window.add_value(e1_name, e2_name, e3_name, e4_name)
self.top.destroy()
在正确输入姓名和手机号等信息后,是对联系人进行保存,本程序是创建一个联系人表格,将联系人信息保存入文件中,其保存代码和创建文件与写入文件如下所示:
# 保存联系人到文件
def save_all_contacts(self):
self.cancel_search(None)
f = open("contacts.csv", "w", encoding='utf-8')
for contact in self.contacts:
str = '%s,%s,%s,%s\n' % (contact.name, contact.phone_number, contact.work_place, contact.e_mail)
f.write(str)
f.close()
messagebox.showinfo('提示', '保存 %d 位联系人到文件成功!' % len(self.contacts))
在程序运行过程中也会弹出提示框,提示您保存成功,如图4.4所示:
图4.4保存成功
随后我们可以找到该文件并打开,就可以看到已经保存的联系人,如图4.5所示:
图4.5打开文件查看保存联系人
在通讯录的界面会显示已经添加的联系人信息,在此时如果想要查看其中一个联系人的基本信息,只需要将鼠标左键连续点击该联系人,就会跳出弹窗,显示所选联系人的基本信息,方便简单易学。界面如图4.6所示:
图4.6显示基本信息
代码如下所示:
# 双击联系人条目
def dbclick(self, event):
selection = self.lb.curselection()
self.sel_item = selection[0]
self.right_clidk_reset(is_dbclick=True)
contact = self.contacts[self.sel_item]
wp = contact.work_place if len(contact.work_place) != 0 else '空'
em = contact.e_mail if len(contact.e_mail) != 0 else '空'
msg = '姓名:%s\n电话:%s\n工作单位:%s\nE-mail地址:%s' % (contact.name, contact.phone_number, wp, em)
messagebox.showinfo("详细信息", msg)
在通讯录的显示框口中,可以先选中联系人再鼠标右键编辑和删除该联系人,这个设计节省了再设置修改联系人的按钮,再实现上也更加方便了,显示效果如图4.7所示:
图4.7右键编辑删除联系人
该操作也是包含判定修改后的联系人信息是否完整,若姓名、手机号二者缺一也是不可保存且有提示框弹出。代码如下:
def rclick_popup(self, event):
a_menu = Menu(self.root, tearoff=0)
a_menu.add_command(label='编辑选中的联系人', command=self.edit_contact)
a_menu.add_command(label='删除选中的联系人', command=self.del_contact)
a_menu.post(event.x_root, event.y_root)
# 右键编辑选中的联系人
def edit_contact(self):
selection = self.lb.curselection()
if len(selection) == 0:
messagebox.showerror("出错了", '请先左键选中待操作的联系人!')
return
self.sel_item = selection[0]
self.right_clidk_reset()
contact = self.contacts[self.sel_item]
self.popup("编辑联系人", contact=contact)
# 右键删除选中的联系人
def del_contact(self):
selection = self.lb.curselection()
if len(selection) == 0:
messagebox.showerror("出错了", '请先左键选中待操作的联系人!')
return
self.right_clidk_reset()
answer = messagebox.askyesno("提示", "您确定要删除此联系人吗?")
if answer:
self.lb.delete(self.sel_item, self.sel_item)
self.contacts.pop(self.sel_item)
self.label.config(text='系统现有 %d 位联系人' % len(self.contacts))
messagebox.showinfo('提示', '联系人从列表删除成功!\n若需要保存操作结果,请点击“保存所有联系人”')
删除所有联系人类似于将通讯录恢复出厂设置,里面的内容会被清空,得到一个新的通讯录,如图4.8所示:
图4.8删除所有联系人
在点击确定会,通讯录会返回初始值,代码如下所示:
# 删除所有联系人
def del_all_contacts(self):
self.cancel_search(None)
answer = messagebox.askyesno("提示", "您确定要删除所有联系人吗?")
if answer:
self.contacts.clear()
self.lb.delete(0, END)
remove("contacts.csv")
self.label.config(text='系统现有 %d 位联系人' % len(self.contacts))
在通讯录的左下角有一个提示“系统现有%d位联系人”,这是为了统计方便一目了然,但实际用途并不是很大。如图4.9所示:
.9系统现有%d位联系人
代码如下所示:
# 添加界面底部联系人数
def add_statusbar_widget(self):
frame = Frame(self.root)
frame.pack(pady=8, side=LEFT)
self.label = Label(frame, text='>系统现有 0 位联系人<')
elf.label.pack()
在前面的详细设计中已经介绍了两种搜索方法,这里只要讲第二种搜索方法,在主界面有一个框架内写着“输入部分姓名或电话号码按回车查询”,这个就是搜索框架,只要将鼠标左键敲击此处,提示字样就会消失,此时你只需要输入联系人的名字或者手机号即可搜索,切不可二者同时输入。如图4.10所示:
图4.10点击搜索框
在框架内输入张三或者123123,再或者只要输入部分姓名和手机号然后回车就可以得到想要搜索的联系人信息,如图4.11所示:
图4.11输入张三
代码实现如下所示:
# 搜索联系人方法
def search_contact(self, event):
self.search_btn["state"] = "normal"
self.lb.delete(0, END)
key = self.input_view.get().strip()
ci = 0
for contact in self.contacts:
if (key in contact.name) or (key in contact.phone_number):
self.lb.insert(END, '%s Tel:%s' % (contact.name, contact.phone_number))
ci += 1
self.label.config(text='查询到 %d 位联系人' % ci)
# 取消搜索
def cancel_search(self, event):
b_state = self.search_btn["state"]
if b_state == "normal":
self.search_btn["state"] = "disabled"
self.lb.delete(0, END)
self.input_view.delete(0, END)
self.input_view.insert(0, '输入部分姓名或电话号码按回车查询')
for contact in self.contacts:
self.lb.insert(END, '%s Tel:%s' % (contact.name, contact.phone_number))
self.label.config(text='系统现有 %d 位联系人' % len(self.contacts))
self.input_view.selection_range(0, len(self.input_view.get()))
由于时间不是很充足的原因,有一些想好的东西还没有加入,结束的有一些仓促,也因为时第一次写一个完整的代码,大家都很紧张,在发挥上会出现一些问题,不过一个团队都很团结,大家一起挺了过去,经过这周的课程设计,大家提高了实际操作能力和思想的远见能力,做到真正的由感性认识上升到了理性认识再到实际的操作中,真正做到学以致用。
[1] 黑马程序员.Python程序开发案例教程,中国铁道出版社,2019.10
[2] 明日科技.Python项目开发案例集锦,吉林大学出版社,2019.3
[3] 郑秋生等.Python项目案例开发从入门到实战——爬虫、游戏和机器学习,清华大学出版社,2019.1