美文网首页
用 Python 开发名片管理系统

用 Python 开发名片管理系统

作者: 哎吆喂轩 | 来源:发表于2017-11-08 10:56 被阅读0次

简介

这是一个用 Python 开发的可视化的名片管理系统,主要实现名片的添加、删除、修改三大功能。效果图如下所示


首页 添加页面

思路分析

界面实现:使用 Tkinter 库进行 GUI 界面设计开发。tkinter 是 python 内置的一套用于开发 GUI 程序的包。

数据存储:1.0版本的数据在内存中以列表形式存储,序列化到本地时使用文件存储方案

# 所有数据集合
self.all_items = []

代码结构:项目有三个窗口,分别是主界面、添加界面,修改界面,每一个界面使用一个类进行组织,并提供一个 show 方法,用于显示窗口,因为添加和修改界面可以公用,所以只需定义两个界面类即可。

  • 主界面:MainFrame
  • 添加/修改界面:InputFrame
    代码结构如下所示


    类结构

    程序启动时,新建主界面的实例对象,然后调用 show 方法即可运行程序。


    image.png

开发环境

  • 开发工具:Pycharm
  • 辅助包:tkinter

代码实现

from tkinter import *
from tkinter import messagebox

# 定义一个主窗口界面类,其父类为 object
class MainFrame(object):
    # 初始化主窗口
    def __init__(self):
        # 初始化所有数据集合列表
        self.all_items = []
        # 使用Tk()函数创建顶级窗口(主窗口)
        self.root = Tk()
        # 窗口自定义名称为“名片管理系统”
        self.root.title("名片管理系统")
        # 设置主窗口大小
        self.root.wm_minsize(width=400, height=300)

    # 定义 show 方法:显示主窗口布局
    def show(self):
        # 显示顶部区域信息
        self.addTopFrame()
        # 初始化信息列表区域
        self.initContent()
        # 从本地文件加载以存储的信息
        self.loadData()
        # 显示出所有的名片信息
        self.showAllItem()
        # 开启主界面,进入主循环
        self.root.mainloop()

    # 定义 showAllItem 方法,显示所有列表信息
    def showAllItem(self):
        # 遍历循环所有的列表信息
        for data in self.all_items:
            # 添加信息到列表界面
            self.showItem(data)

    # 定义 save_2_file 方法,将已经添加的名片信息存储到本地文件中
    def save_2_file(self):
        # 打开文件
        f = open("contacts.data", "w")
        # 将已经添加的信息以字符串形式写入次文件
        f.write(str(self.all_items))
        # 关闭文件
        f.close()

    # 定义一个loadData方法,加载本地存储文件中的所有数据
    def loadData(self):
        # 通过"try...except"异常点检验方法,检查存储名片信息的本地文件的存在性
        try:
            # 打开存储名片信息的本地文件
            f = open("contacts.data")
            # 读取本地文件中的所有数据
            self.all_items = eval(f.read())
            """eval 相关知识点以及用法
            功能:将字符串str当成有效的表达式来求值并返回计算结果。
          语法: eval(source[, globals[, locals]]) -> value
            参数:source:一个Python表达式或函数compile()返回的代码对象
                  globals:可选。必须是dictionary
                  locals:可选。任意map对象"""
            f.close()
        except Exception:
            pass

    # 添加主窗口布局需要的控件
    def addTopFrame(self):
        # 添加一个框架将首页的题目和添加按钮都放在一起
        topFrame = Frame(self.root)
        # 在次框架中添加一个标签,其题目:名片信息
        titlelable = Label(topFrame, text="名片信息")
        # 显示框架,并设定向左排列,x和y轴的宽度均为5个像素
        titlelable.pack(side=LEFT, padx=5, pady=6)

        # 定义一个添加按钮,其中command点击事件通过lambda函数实现:调用showInputFrame
        addButton = Button(topFrame, text="添加", command=lambda : self.showInputFrame("添加",None))
        # 显示按钮,并设定向左排列,x和y轴的宽度均为默认像素
        addButton.pack(side=RIGHT)

        # 设置此框架的背景颜色为蓝色
        topFrame.config(bg="#3f51b5")
        # 横向填充
        topFrame.pack(fill=X)

    # 显示添加页面
    def showInputFrame(self,title,dict):
        # 定义 inputFrame 实例,即创建一个添加界面
        self.inputFrame = InputFrame(self,title,dict)
        # 显示添加界面
        self.inputFrame.show()

    # 显示列表信息
    def initContent(self):
        # 初始化列表框架
        self.item_container = Frame(self.root)
        # 将这一框架整体整合
        self.item_container.pack()

    # 添加名片信息
    def addItem(self, dict):
        # 添加新信息到 all_items 列表
        self.all_items.append(dict)
        # 显示名片信息
        self.showItem(dict)
        # 将信息保存到本地文件夹
        self.save_2_file()

    # 修改信息
    def updateItem(self, origin_data,new_data):
        # 获取原始数据列表的索引
        index = self.all_items.index(origin_data)
        # 将需要修改的内容从数据列表中移除
        self.all_items.remove(origin_data)
        # 添加修改后的名片信息到数据列表
        self.all_items.insert(index,new_data)
        # 将修改后的信息保存到本地文件夹
        self.save_2_file()

        # 为了让修改后的信息整体生效,先将主界面上的所有信息都删除
        self.remove_allItem()
        # 然后在主界面上重新显示所有信息
        self.showAllItem()

    # 清空主界面上的每一行数据:
    def remove_allItem(self):
        # 通过for循环将主界面上的名片信息都逐一删除
        for child_item in self.item_container.winfo_children():
            child_item.destroy()

    # 在主界面上显示一行信息
    def showItem(self, dict):
        # 初始化主框架
        item_frame = Frame(self.item_container)

        # 添加姓名信息标签
        name_label = Label(item_frame, text=dict['name'])
        name_label.pack(side=LEFT, padx=5, pady=5)

        # 添加性别信息标签
        sex_label = Label(item_frame, text=dict['sex'])
        sex_label.pack(side=LEFT)

        # 添加手机号信息标签
        mob_label = Label(item_frame, text=dict['mobile'])
        mob_label.pack(side=LEFT)

        # 添加删除按钮
        delete_button = Button(item_frame, text="删除", command=lambda: self.delete_item(dict,item_frame))
        # delete_button = Button(f2, text="删除", command=lambda dict : self.all_items.remove(dict))
        delete_button.pack(side=LEFT)

        # 添加修改按钮
        update_button = Button(item_frame, text="修改",command=lambda : self.showInputFrame("修改",dict))
        update_button.pack(side=LEFT)

        # 将整个框架整体封装
        item_frame.pack()

    # 删除信息
    def delete_item(self, data,item_frame):
        # 从数据列表中删除数据
        self.all_items.remove(data)
        # 将删除后的信息存储到本地文件
        self.save_2_file()
        # 在主界面中将删除的这条信息移除
        item_frame.pack_forget()


# 定义了一个添加界面类,其父类为 object
class InputFrame(object):
    def __init__(self, mainFrame,title,dict):
        self.mainFrame = mainFrame
        self.data = dict
        # 初始化添加窗口
        self.inputRootFrame = Tk()
        # 设置这一窗口的题目
        self.inputRootFrame.title(title)
        # 设置窗口大小
        self.inputRootFrame.wm_minsize(width=200, height=250)


    def show(self):
        # 添加界面的展示信息
        self.addInputFrame()
        # 由于添加和编辑用了同一个界面,所以根据界面不同,按钮的文本需要改变
        if self.data == None:
            self.addButtonFrame('保存')
        else:
            self.addButtonFrame('确定修改')

        self.inputRootFrame.mainloop()

    # 添加界面布局信息展示
    def addInputFrame(self):
        # 初始化姓名框架以及界面
        fmname = Frame(self.inputRootFrame)
        # 添加姓名标签
        self.namelable = Label(fmname, text="姓名:")
        # 设置姓名标签的位置以及大小
        self.namelable.pack(side=LEFT, padx=5, pady=10)
        # 添加姓名输入框
        self.nameInput = Entry(fmname, width=50, textvariable=StringVar())
        # 设置姓名输入框的位置
        self.nameInput.pack(side=LEFT)
        # 将以前的姓名自动填写进来,便于用户核对方便修改
        if self.data != None:
            self.nameInput.insert(0, self.data['name'])
            self.nameInput['state'] = DISABLED
        fmname.pack()

        # 初始化性别框架以及信息
        fmSex = Frame(self.inputRootFrame)
        # 添加性别标签
        self.sexlable = Label(fmSex, text="性别:")
        # 设置性别标签的位置
        self.sexlable.pack(side=LEFT, padx=5, pady=10)

        # 添加性别输入框
        self.sexInput = Entry(fmSex, width=50, textvariable=StringVar())
        # 设置性别输入框的位置
        self.sexInput.pack(side=LEFT)
        # 将以前的性别自动填写进来,便于用户核对方便修改
        if self.data != None:
            self.sexInput.insert(0, self.data['sex'])
        fmSex.pack()

        # 初始化手机号的框架以及显示内容
        fmMob = Frame(self.inputRootFrame)
        # 添加手机号标签
        moblelable = Label(fmMob, text="手机号:")
        # 设置手机号标签的位置
        moblelable.pack(side=LEFT, padx=5, pady=10)
        # 添加手机号输入框
        self.mobleInput = Entry(fmMob, width=50, textvariable=StringVar())
        # 设置手机号输入框的位置
        self.mobleInput.pack(side=LEFT)
        # 将以前的手机号自动填写进来,便于用户核对方便修改
        if self.data != None:
            self.mobleInput.insert(0, self.data['mobile'])
        fmMob.pack()

    # 添加界面的按钮设置
    def addButtonFrame(self,title):
        # 初始化框架
        fmButton = Frame(self.inputRootFrame)
        # 设置框架位置
        fmButton.pack(side=BOTTOM, anchor=W, fill=X)

        # 添加保存按钮
        confrmButton = Button(fmButton, text=title, command=self.saveInput)
        confrmButton.pack(side=RIGHT, fill=BOTH)

        # 添加取消按钮
        cencelButton = Button(fmButton, text="取消", command=self.cancelInput)
        cencelButton.pack(side=RIGHT)

    # 名片信息存储
    def saveInput(self):
        # 获取输入的姓名
        name = self.nameInput.get()
        # 获取输入的性别
        sex = self.sexInput.get()
        # 获取输入的手机号
        mobile = self.mobleInput.get()

        # 确保输入的姓名不为空
        if name == None or name == '':
            messagebox.showinfo("提示","请输入姓名!")
            return
        # 确保输入的性别不为空
        if sex == None or sex == '':
            messagebox.showinfo("提示","请输入性别!")
            return
        # 确保输入的性别为“男” 或者 “女”
        if sex != '男' and sex != '女':
            messagebox.showinfo("提示","请选择男或者女!")
            return

        # 确保输入的手机号不为空
        if mobile == None or mobile == '':
            messagebox.showinfo("提示","请输入手机号!")
            return

        # 将输入的整条名片信息以字典的形式存储
        info = {'name': name, 'sex': sex, 'mobile': mobile}
        # 如果在添加页面添加数据成功后,就把数据更新到主界面
        if self.data == None:
            self.mainFrame.addItem(info)
        else:
            self.mainFrame.updateItem(self.data,info)
        # 返回主界面
        self.inputRootFrame.destroy()

    # 点击修改页面上的“取消”按钮,就返回到主界面上
    def cancelInput(self):
        self.inputRootFrame.destroy()


# 程序入口
if __name__ == '__main__':
    # 创建一个 main frame 对象,即创建一个主窗口实例
    mainFrame = MainFrame()
    # 调用主窗口的show()方法显示主窗口
    mainFrame.show()

总结

相关文章

网友评论

      本文标题:用 Python 开发名片管理系统

      本文链接:https://www.haomeiwen.com/subject/stmsmxtx.html