目录
1.引言
快递是现代社会中不可或缺的一种物流服务,它可以将物品从寄件人快速地送达到收件人。随着电子商务的发展,快递业务也呈现出爆发式的增长,同时也带来了快递信息管理的挑战。如何有效地记录、查询和跟踪快递信息,是提高快递服务质量和效率的关键。
为了解决这一问题,本次设计并实现了一个基于Python和tkinter的快递信息管理系统。该系统可以实现以下功能:
添加快递信息:用户可以输入寄件人、收件人、快递单号、快递公司和快递状态等信息,将其添加到系统中。
查看快递信息:用户可以查看系统中存储的所有快递信息,以列表形式显示在界面上。
搜索快递信息:用户可以输入搜索关键字,根据运单号或收件人来搜索匹配的快递信息,并显示在界面上。
保存快递信息:用户可以将系统中存储的所有快递信息保存到json文件中,以便于备份和恢复。
2.系统需求分析
功能需求
功能需求是指系统应该提供的具体功能,本系统的功能需求如下:
添加快递信息:用户可以输入寄件人、收件人、快递单号、快递公司和快递状态等信息,将其添加到系统中。系统应该对用户的输入进行合法性检查,如快递单号是否为空,是否重复等。添加成功后,系统应该提示用户,并更新界面上的快递信息列表。
查看快递信息:用户可以查看系统中存储的所有快递信息,以列表形式显示在界面上。列表中应该显示每条快递信息的寄件人、收件人、快递单号、快递公司和快递状态等信息。用户可以通过滚动条来浏览列表中的内容。
搜索快递信息:用户可以输入搜索关键字,根据运单号或收件人来搜索匹配的快递信息,并显示在界面上。搜索时,系统应该支持模糊匹配,即只要关键字是运单号或收件人的一部分,就可以匹配到相应的快递信息。搜索结果应该以列表形式显示在界面上,与查看功能相同。如果没有找到匹配的快递信息,系统应该提示用户。
保存快递信息:用户可以将系统中存储的所有快递信息保存到json文件中,以便于备份和恢复。保存时,系统应该让用户选择保存文件的位置和名称,并对文件进行写入操作。保存成功后,系统应该提示用户。
非功能需求
非功能需求是指系统应该满足的一些质量属性,本系统的非功能需求如下:
可用性:系统应该易于使用,提供友好和直观的用户界面,以及清晰和准确的提示信息。系统应该能够处理用户的各种输入,并给出合理的反馈。
可靠性:系统应该能够稳定地运行,在正常情况下不出现错误或异常。如果出现错误或异常,系统应该能够恢复并继续运行,并给出相应的提示信息。
可维护性:系统应该遵循良好的编程规范和风格,代码应该清晰和规范,注释应该完整和详细。系统应该具有良好的模块化和封装性,方便修改和扩展。
3.系统架构设计
系统总体架构
本系统采用了基于Python和tkinter开发桌面应用程序的方式。
系统主要由以下几个部分组成:
用户界面层:负责与用户交互,接收用户的输入,显示系统的输出,提供友好和直观的用户界面。该层使用tkinter模块来创建和管理各种控件,如标签、输入框、按钮、列表框等。
业务逻辑层:负责实现系统的核心功能,处理用户的请求,执行相应的操作,返回相应的结果。该层使用Python语言来编写各个功能模块,如添加、查看、搜索和保存快递信息等。
数据访问层:负责与数据文件进行交互,读取和保存快递信息数据。该层使用json模块来对数据文件进行读写操作,将快递信息数据以json格式存储在文件中。
系统模块划分
根据系统的功能需求,本系统可以划分为以下几个模块:
添加快递信息模块:实现添加快递信息的功能,包括获取用户输入的快递信息,检查其合法性,将其添加到数据列表中,并保存到数据文件中。
查看快递信息模块:实现查看快递信息的功能,包括从数据文件中读取快递信息数据,并以列表形式显示在界面上。
搜索快递信息模块:实现搜索快递信息的功能,包括获取用户输入的搜索关键字,并根据运单号或收件人来匹配快递信息,并以列表形式显示在界面上。
保存快递信息模块:实现保存快递信息的功能,包括将数据列表中的快递信息数据保存到数据文件中。
4.系统模块设计
添加快递信息模块
添加快递信息模块的功能是实现添加快递信息的功能,包括获取用户输入的快递信息,检查其合法性,将其添加到数据列表中,并保存到数据文件中。该模块由以下几个函数组成:
add_express(): 主函数,负责调用其他函数来完成添加快递信息的功能。
get_input(): 获取用户输入的快递信息,并返回一个字典对象。
check_input(): 检查用户输入的快递信息是否合法,并返回一个布尔值。
append_data(): 将用户输入的快递信息添加到数据列表中,并返回一个布尔值。
save_data(): 将数据列表中的快递信息保存到数据文件中,并返回一个布尔值。
该模块的接口如下:
# 添加快递信息模块
def add_express():
# 获取用户输入的快递信息
express = get_input()
# 检查用户输入的快递信息是否合法
if check_input(express):
# 将用户输入的快递信息添加到数据列表中
if append_data(express):
# 将数据列表中的快递信息保存到数据文件中
if save_data(data):
# 提示用户添加成功,并更新界面上的快递信息列表
tk.messagebox.showinfo('提示', '添加成功!')
update_listbox()
else:
# 提示用户保存失败
tk.messagebox.showwarning('警告', '保存失败!')
else:
# 提示用户添加失败
tk.messagebox.showwarning('警告', '添加失败!')
else:
# 提示用户输入不合法
tk.messagebox.showwarning('警告', '输入不合法!')
# 清空用户输入的快递信息
clear_entry_fields()
查看快递信息模块
查看快递信息模块的功能是实现查看快递信息的功能,包括从数据文件中读取快递信息数据,并以列表形式显示在界面上。该模块由以下几个函数组成:
view_express(): 主函数,负责调用其他函数来完成查看快递信息的功能。
load_data(): 从数据文件中读取快递信息数据,并返回一个列表对象。
update_listbox(): 将快递信息数据以列表形式显示在界面上。
该模块的接口如下:
# 查看快递信息模块
def view_express():
# 从数据文件中读取快递信息数据
data = load_data()
# 将快递信息数据以列表形式显示在界面上
update_listbox(data)
搜索快递信息模块
搜索快递信息模块的功能是实现搜索快递信息的功能,包括获取用户输入的搜索关键字,并根据运单号或收件人来匹配快递信息,并以列表形式显示在界面上。该模块由以下几个函数组成:
search_express(): 主函数,负责调用其他函数来完成搜索快递信息的功能。
get_keyword(): 获取用户输入的搜索关键字,并返回一个字符串对象。
match_express(): 根据运单号或收件人来匹配快递信息,并返回一个列表对象。
update_listbox(): 将匹配的快递信息以列表形式显示在界面上。
该模块的接口如下:
# 搜索快递信息模块
def search_express():
# 获取用户输入的搜索关键字
keyword = get_keyword()
# 根据运单号或收件人来匹配快递信息
matches = match_express(keyword)
# 将匹配的快递信息以列表形式显示在界面上
update_listbox(matches)
保存快递信息模块
保存快递信息模块的功能是实现保存快递信息的功能,包括将数据列表中的快递信息数据保存到数据文件中。该模块由以下几个函数组成:
save_express(): 主函数,负责调用其他函数来完成保存快递信息的功能。
get_file_path(): 获取用户选择的保存文件的位置和名称,并返回一个字符串对象。
save_data(): 将数据列表中的快递信息数据保存到数据文件中,并返回一个布尔值。
该模块的接口如下:
# 保存快递信息模块
def save_express():
# 获取用户选择的保存文件的位置和名称
file_path = get_file_path()
# 判断用户是否选择了文件
if file_path:
# 将数据列表中的快递信息数据保存到数据文件中
if save_data(data, file_path):
# 提示用户保存成功
tk.messagebox.showinfo('提示', '保存成功!')
else:
# 提示用户保存失败
tk.messagebox.showwarning('警告', '保存失败!')
else:
# 提示用户取消了选择
tk.messagebox.showinfo('提示', '取消了选择!')
5.系统算法与数据结构
数据的存储
本系统使用json文件来存储快递信息数据,json文件是一种轻量级的数据交换格式,可以用文本表示复杂的数据结构,方便读写和解析。json文件的基本格式如下:
[
{
"sender": "寄件人1",
"receiver": "收件人1",
"express_no": "快递单号1",
"express_company": "快递公司1",
"status": "状态1"
},
{
"sender": "寄件人2",
"receiver": "收件人2",
"express_no": "快递单号2",
"express_company": "快递公司2",
"status": "状态2"
},
...
]
如上所示,json文件中的数据是一个列表,列表中的每个元素是一个字典,字典中包含了快递信息的五个属性:寄件人、收件人、快递单号、快递公司和状态。每个属性都是一个字符串类型的值。
本系统使用json模块来对json文件进行读写操作,json模块提供了两个主要的函数:
json.load(f): 从一个文件对象f中读取json格式的数据,并返回一个Python对象,如列表或字典。
json.dump(obj, f): 将一个Python对象obj,如列表或字典,转换为json格式的数据,并写入到一个文件对象f中。
数据的操作
本系统对快递信息数据进行了以下几种操作:
添加:将用户输入的快递信息添加到数据列表中,并保存到数据文件中。
查看:从数据文件中读取快递信息数据,并以列表形式显示在界面上。
搜索:根据运单号或收件人来匹配快递信息,并以列表形式显示在界面上。
保存:将数据列表中的快递信息数据保存到数据文件中。
这些操作都是通过调用相应的函数来实现的,具体的函数实现已经在第四章中介绍过,这里不再赘述。
6.系统评价
系统优点
本系统具有以下几个优点:
功能完善:系统实现了快递信息的添加、查看、搜索和保存功能,满足了用户的基本需求。
界面友好:系统提供了友好和直观的用户界面,以及清晰和准确的提示信息,方便用户使用。
代码规范:系统遵循了良好的编程规范和风格,代码清晰和规范,注释完整和详细,便于阅读和维护。
模块化设计:系统采用了模块化设计的思想,将系统划分为不同的模块,每个模块负责一个功能,具有良好的封装性和可复用性。
系统缺点
本系统也存在以下几个缺点:
数据存储方式单一:系统只支持将快递信息数据存储在json文件中,不支持其他格式或方式的存储,如数据库、XML等。
搜索功能简单:系统只支持根据运单号或收件人来搜索快递信息,不支持其他条件或方式的搜索,如寄件人、快递公司、快递状态等。
界面美观度低:系统使用了tkinter模块提供的默认控件和样式,没有进行美化或定制,界面美观度较低。
7.附录
源代码
import json
import tkinter as tk
# 数据存储文件名
DATA_FILE = r'E:\Python\data.json'
# 初始化快递信息数据
def init_data():
return []
# 读取快递信息数据
def load_data():
try:
with open(DATA_FILE, 'r', encoding='utf-8') as f:
data = json.load(f)
# 检查数据是否是一个列表,且列表中的每个元素都是一个包含sender, receiver, express_no, express_company, status这些键的字典
if isinstance(data, list) and all(isinstance(express, dict) and all(key in express for key in ('sender', 'receiver', 'express_no', 'express_company', 'status')) for express in data):
return data
else:
# 如果数据格式不正确,返回一个空列表
return init_data()
except FileNotFoundError:
# 如果文件不存在,返回一个空列表
return init_data()
except json.JSONDecodeError:
# 如果文件内容不是合法的json格式,返回一个空列表
return init_data()
# 保存快递信息数据
def save_data(data):
try:
with open(DATA_FILE, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False)
except IOError:
# 如果文件写入失败,显示一个错误提示框
tk.messagebox.showerror('错误', '保存数据失败,请检查文件路径和权限。')
# 添加快递信息
def add_express():
# 获取Entry控件的输入值
sender = sender_var.get().strip()
receiver = receiver_var.get().strip()
express_no = express_no_var.get().strip()
express_company = express_company_var.get().strip()
status = status_var.get().strip()
# 检查输入值是否为空,如果为空,显示一个警告提示框,并返回
if not sender or not receiver or not express_no or not express_company or not status:
tk.messagebox.showwarning('警告', '请填写完整的快递信息。')
return
# 构造一个快递信息的字典
express = {'sender': sender, 'receiver': receiver, 'express_no': express_no, 'express_company': express_company, 'status': status}
# 将快递信息添加到数据列表中
data.append(express)
# 保存数据到文件中
save_data(data)
# 更新Listbox控件的显示内容
update_listbox()
# 清空Entry控件的输入内容
clear_entry_fields()
# 查看快递信息
def view_express():
# 清空Listbox控件的显示内容
listbox.delete(0, tk.END)
# 判断数据列表是否为空
if len(data) == 0:
# 如果为空,显示提示信息
listbox.insert(tk.END, '暂无快递信息。')
else:
# 如果不为空,遍历数据列表,显示每条快递信息
for express in data:
listbox.insert(tk.END, '寄件人:{},收件人:{},快递单号:{},快递公司:{},状态:{}'.format(express['sender'], express['receiver'], express['express_no'], express['express_company'], express['status']))
# 搜索快递信息
def search_express():
# 获取搜索框的输入值
keyword = keyword_var.get().strip()
# 清空Listbox控件的显示内容
listbox.delete(0, tk.END)
# 判断数据列表是否为空
if len(data) == 0:
# 如果为空,显示提示信息
listbox.insert(tk.END, '暂无快递信息。')
else:
# 如果不为空,设置一个标志变量,表示是否找到匹配的快递信息
found = False
# 遍历数据列表,根据运单号或收件人来搜索快递信息
for express in data:
if keyword in express['express_no'] or keyword in express['receiver']:
# 如果找到匹配的快递信息,显示在Listbox控件中,并将标志变量设为True
listbox.insert(tk.END, '寄件人:{},收件人:{},快递单号:{},快递公司:{},状态:{}'.format(express['sender'], express['receiver'], express['express_no'], express['express_company'], express['status']))
found = True
# 如果遍历完数据列表后,标志变量仍为False,表示没有找到匹配的快递信息,显示提示信息
if not found:
listbox.insert(tk.END, '没有找到相关的快递信息。')
# 更新Listbox控件的显示内容
def update_listbox():
view_express()
# 清空Entry控件的输入内容
def clear_entry_fields():
sender_var.set('')
receiver_var.set('')
express_no_var.set('')
express_company_var.set('')
status_var.set('已发货')
if __name__ == "__main__":
# 初始化数据
data = load_data()
# 创建主窗口
root = tk.Tk()
root.title('快递信息管理系统')
# 设置窗口大小和位置
root.geometry('400x400+300+100')
# 创建控件
sender_label = tk.Label(root, text='寄件人:', font=('宋体', 12))
sender_var = tk.StringVar()
# 设置 sender_entry 控件的宽度为20
sender_entry = tk.Entry(root, textvariable=sender_var, font=('宋体', 12), width=20)
receiver_label = tk.Label(root, text='收件人:', font=('宋体', 12))
receiver_var = tk.StringVar()
# 设置 receiver_entry 控件的宽度为20
receiver_entry = tk.Entry(root, textvariable=receiver_var, font=('宋体', 12), width=20)
express_no_label = tk.Label(root, text='快递单号:', font=('宋体', 12))
express_no_var = tk.StringVar()
# 设置 express_no_entry 控件的宽度为20
express_no_entry = tk.Entry(root, textvariable=express_no_var, font=('宋体', 12), width=20)
express_company_label = tk.Label(root, text='快递公司:', font=('宋体', 12))
express_company_var = tk.StringVar()
# 设置 express_company_entry 控件的宽度为20
express_company_entry = tk.Entry(root, textvariable=express_company_var, font=('宋体', 12), width=20)
status_label = tk.Label(root, text='快递状态:', font=('宋体', 12))
status_var = tk.StringVar(value='已发货')
status_optionmenu = tk.OptionMenu(root, status_var, '已发货', '已到达', '已签收', '问题件')
add_button = tk.Button(root, text='添加', command=add_express)
view_button = tk.Button(root, text='查看', command=view_express)
# 创建一个垂直滚动条对象,并与Listbox控件关联起来
scrollbar = tk.Scrollbar(root)
listbox = tk.Listbox(root, height=10)
# 设置 Listbox 控件的宽度为50,并与滚动条关联起来
listbox.config(width=50, yscrollcommand=scrollbar.set)
scrollbar.config(command=listbox.yview)
keyword_label = tk.Label(root, text='搜索关键字:', font=('宋体', 12))
keyword_var = tk.StringVar()
# 设置 keyword_entry 控件的宽度为20
keyword_entry = tk.Entry(root, textvariable=keyword_var, font=('宋体',12))
search_button = tk.Button(root, text='搜索', command=search_express)
# 布局控件
sender_label.place(x=20,y=20)
sender_entry.place(x=100,y=20)
receiver_label.place(x=20,y=60)
receiver_entry.place(x=100,y=60)
express_no_label.place(x=20,y=100)
express_no_entry.place(x=100,y=100)
express_company_label.place(x=20,y=140)
express_company_entry.place(x=100,y=140)
status_label.place(x=20,y=180)
status_optionmenu.place(x=100,y=180)
add_button.place(x=80,y=220)
view_button.place(x=200,y=220)
listbox.place(x=20,y=260,width=360,height=120)
keyword_label.place(x=20,y=390)
keyword_entry.place(x=120,y=390)
search_button.place(x=300,y=390)
# 启动主循环
root.mainloop()
运行环境
本系统的运行环境如下:
操作系统:Windows 10
Python版本:3.9.7
tkinter模块版本:8.6
json模块版本:2.0.9
运行截图