Python实现简易信息分类存储软件
本文介绍了一款基于Python开发的简易信息分类存储软件。项目利用tkinter构建图形界面,结合sqlite3进行数据存储,支持增删改查、汇总展示及CSV导出功能。通过内置库实现打包兼容性,旨在快速满足特定场景下的信息管理需求。
项目背景与需求分析
面对紧迫的时间与模糊的需求,需要自行考虑各种可能情况,除了使用Python,很难在短时间内完成此类开发任务。

技术选型与界面设计
程序界面需具备增删改查功能,并预留“后悔药”机制。考虑到最终需打包交付,项目选用Python自带库tkinter编写界面,虽外观普通但实用;数据存储采用sqlite3数据库,支持导出为csv文件,全程使用Python内置库以确保打包后的兼容性。

查询功能实现
查询界面支持按各表项目分类检索,若未输入查询关键字,则输出当前类别的全部数据。

初始界面展示
汇总信息展示区域作为程序的初始界面。
直接展示代码实现。由于是业余时间开发,代码风格简单直接,经过多次修补完善,敬请指正。
核心代码实现
import tkinter as tk
import sqlite3
import csv
from threading import Thread
import shutil
import os
import time
from tkinter import messagebox
from tkinter import filedialog
from tkinter import ttk
class App(tk.Frame):
def __init__(self,master,*args,**kwargs):
super().__init__(master,*args,**kwargs)
self.dirdict={
"新建":self.new,
"查询":self.search,
"修改":self.edit,
"删除":self.delete,
"汇总":self.totale,
"导出":self.export,
"后悔药":self.regret
}
self.newdict={
"咨询信息":self.customer_information,
"投标信息":self.bidding_information,
"合同信息" :self.contract_information,
"售后信息" :self.service_information,
}
self.newlabelsdict={
"咨询信息":["日期","公司名称","联系人","联系电话","备注"],
"投标信息":["招标单位","招标号","报名费","保证金","退保证金","开票信息",],
"合同信息":["合同号","签订日期","数量","总价","客户名称","货期","派工单号","发货地址","回款批次","发票信息","开票信息","合同扫描件"],
"售后信息":["产品型号","派工号","货期","技术人员","安装人员","验收","售后1","售后2"],
}
self.prmkey={
"咨询信息":('company',1),
"投标信息":('company',0),
"合同信息":('contract',0),
"售后信息":('jobnum',1),
}
self.new_zh_col={
"咨询信息":'consulting',
"日期":"date","公司名称":"company","联系人":"contacts","联系电话":"telephone","备注":"remarks",
"投标信息":'bid',
"招标单位":"company","招标号":"number","报名费":"enroll","保证金":"ensure","退保证金":"back","开票信息":"invoice",
"合同信息":'contractinfo',
"合同号":"contract","签订日期":"sdate","数量":"quantity","总价":"total","客户名称":"customer","货期":"delivery","派工单号":"oddnum","发货地址":"address","回款批次":"batch","发票信息":"cinfo","开票信息":"invoice","合同扫描件":"catpath",
"售后信息":'service',
"产品型号":"product","派工号":"jobnum","货期":"delivery","技术人员":"artisan","安装人员":"installer","验收":"check","售后1":"service1","售后2":"service2",
}
self.pack(expand=1,fill="both")
self.con=sqlite3.connect("treasure.db")
self.creat_widget()
def creat_widget(self):
self.frameleft = tk.Frame(self,bg='RoyalBlue',relief="groove",borderwidth=2)
self.frameleft.pack(side='left',expand='no',fill='y',anchor="n")
for i in self.dirdict.keys():
but=tk.Button(self.frameleft,text=i,width="10",)
but.pack(side="top",expand="no",fill="x",anchor="n",padx=4,pady=5,)
but.bind('<Button-1>', self.set_style)
self.frameright = tk.Frame(self,bg='RoyalBlue',relief="groove",borderwidth=2)
self.frameright.pack(side='right',expand='yes',fill='both',padx=3,pady=0)
self.lf2 = tk.LabelFrame(self.frameright,text="信息",relief="groove",borderwidth=1,bg="Wheat")
self.lf2.pack(side="top",expand=1,fill="both",pady=2,)
self.totale()
def set_style(self,event):
for i in self.frameleft.winfo_children():
if isinstance(i,tk.Button):
i.config(fg="black")
event.widget["fg"]="blue"
self.reset(self.frameright)
self.lf1 = tk.Frame(self.frameright,relief="groove",borderwidth=0,bg='RoyalBlue')
self.lf1.pack(side="top",expand=0,fill="x",pady=2,)
self.lf2 = tk.LabelFrame(self.frameright,text="信息",relief="groove",borderwidth=1,bg="Wheat")
self.lf2.pack(side="top",expand=1,fill="both",pady=2,)
self.dirdict.get(event.widget["text"],None)()
self.lf2["text"]=event.widget["text"]
######################################新建内容###########################################################################
def new(self):#新建总类
def data_input(event):
self.lf2.config(text=event.widget['text'])
self.reset(self.lf2)
self.newdict.get(event.widget['text'],None)(self.newlabelsdict[event.widget['text']])
for i in self.newdict.keys():
bu=tk.Button(self.lf1,text=i,)
bu.pack(side="left",expand=1,fill="x",padx=5,pady=2,)
bu.bind('<Button-1>', data_input)
def customer_information(self,labellist):#新建客户信息
this="咨询信息"
for i in labellist:
if i == labellist[-1]:
tk.Label(self.lf2,text=i,bg="Wheat",width=10).pack(side="top",)
tk.Text(self.lf2,height=6).pack(side="top",expand=1,pady=1,padx=5,fill="both")
else:
e=tk.Entry(self.lf2,)
e.pack(side="top",expand=0,pady=1,padx=5,fill="x")
l=tk.Label(e,text=i,bg="Wheat",width=10)
l.pack(side="right",)
def getdict():
cusdict=self.super_get(labellist,self.lf2)
if self.save_data("INSERT INTO consulting VALUES (?,?,?,?,?)", list(cusdict.values())):
self.super_del(self.lf2)
bu=tk.Button(self.lf2,text="确认提交",width=15,command=getdict)
bu.pack(side="bottom",expand=0,padx=5,pady=2,)
def bidding_information(self,labellist):#新建招标信息
this="投标信息"
for i in labellist:
if i == labellist[-1]:
tk.Label(self.lf2,text=i,bg="Wheat",width=10).pack(side="top",)
tk.Text(self.lf2,height=6).pack(side="top",expand=1,pady=1,padx=5,fill="both")
else:
e=tk.Entry(self.lf2,)
e.pack(side="top",expand=0,pady=1,padx=5,fill="x")
l=tk.Label(e,text=i,bg="Wheat",width=10)
l.pack(side="right",)
def getdict():
cusdict=self.super_get(labellist,self.lf2)
if self.save_data("INSERT INTO bid VALUES (?,?,?,?,?,?)", list(cusdict.values())):
self.super_del(self.lf2)
bu=tk.Button(self.lf2,text="确认提交",width=15,command=getdict)
bu.pack(side="bottom",expand=0,padx=5,pady=2,)
def contract_information(self,labellist):#新建合同信息
this="合同信息"
def filenames():
names=filedialog.askopenfilenames(title="上传合同扫描件")
if names:
filenamesentry.insert(0,",".join(names))
for i in labellist:
if i==labellist[0]:
connum=tk.Entry(self.lf2,)
connum.pack(side="top",expand=0,pady=1,padx=5,fill="x")
tk.Label(connum,text=i,bg="Wheat",width=10).pack(side="right",)
elif i == labellist[-2]:
tk.Label(self.lf2,text=i,bg="Wheat",width=10).pack(side="top",)
tk.Text(self.lf2,height=6).pack(side="top",expand=1,pady=1,padx=5,fill="both")
elif i==labellist[-1]:
filenamesentry=tk.Entry(self.lf2)
filenamesentry.pack(side="top",expand=0,pady=2,padx=5,fill="x")
filebut=tk.Button(filenamesentry,text="点击上传合同",height=1,command=filenames)
filebut.pack(side="right",expand=0,padx=0,pady=0,)
else:
e=tk.Entry(self.lf2,)
e.pack(side="top",expand=0,pady=1,padx=5,fill="x")
tk.Label(e,text=i,bg="Wheat",width=10).pack(side="right",)
def getdict():
files=filenamesentry.get()
if files:
number=connum.get() if connum.get() else "无合同号"
newcat=os.path.join(os.getcwd(),"mydata\{}{}".format(number,time.strftime(r"-%Y-%m-%d %H-%M-%S",time.localtime()),))
os.mkdir(newcat)
for i in files.split(","):
shutil.move(os.path.join(i),newcat)
filenamesentry.delete(0, "end")
filenamesentry.insert(0,newcat)
cusdict=self.super_get(labellist,self.lf2)
if self.save_data("INSERT INTO contractinfo VALUES (?,?,?,?,?,?,?,?,?,?,?,?)", list(cusdict.values())):
self.super_del(self.lf2)
bu=tk.Button(self.lf2,text="确认提交",width=15,command=getdict)
bu.pack(side="bottom",expand=0,padx=5,pady=2,fill="x")
def service_information(self,labellist):#新建售后信息
this="售后信息"
for i in labellist:
e=tk.Entry(self.lf2,)
e.pack(side="top",expand=0,pady=1,padx=5,fill="x")
l=tk.Label(e,text=i,bg="Wheat",width=10)
l.pack(side="right",)
def getdict():
cusdict=self.super_get(labellist,self.lf2)
# check=self.check(self.new_zh_col.get(this,None),self.prmkey.get(this,None)[0],cusdict.get())
if self.save_data("INSERT INTO service VALUES (?,?,?,?,?,?,?,?)", list(cusdict.values())):
self.super_del(self.lf2)
bu=ttk.Button(self.lf2,text="确认提交",width=15,command=getdict)
bu.pack(side="bottom",expand=0,padx=5,pady=2,)
#################################################################################################################
def save_data(self,sqldoc,somedata,flag=False):#数据库存储存储客户信息
cur = self.con.cursor()
try:
cur.execute(sqldoc,somedata)
self.con.commit()
messagebox.showinfo("禀报女王","女王万岁,您又赢了")
return True
except Exception as e:
messagebox.showwarning("急报女王","女王我出错了:{}".format(e))
return False
def check(self,this,col,value):
sqldoc="SELECT * FROM {} WHERE {} = '{}' ".format(this,col,value)
cur = self.con.cursor()
cur.execute(sqldoc)
data=cur.fetchone()
return data
def find_data(self,sqldoc):
cur = self.con.cursor()
try:
cur.execute(sqldoc)
datas=cur.fetchall()
if datas:
return datas
else:
messagebox.showwarning("禀报女王","女王大人,小的什么也没搜到")
except Exception as e:
messagebox.showwarning("禀报女王","女王大人这是一次失误{}".format(e))
return None
def del_data(self,sqldoc):
cur = self.con.cursor()
cur.execute(sqldoc)
self.con.commit()
messagebox.showinfo("喜报","女王无敌,敌人已消灭")
def add_top(self,title):#创建顶级窗口
top = tk.Toplevel(width=self.master.winfo_screenwidth()//4,height=self.master.winfo_screenheight()//4,)
top.title(title)
return top
def reset(self,widget):#重置该组件,销毁该组件所有子组件
for i in widget.winfo_children():
i.destroy()
def super_get(self,labellist,wids):#获取entry和text类得内容
cusdict={}
for i ,k in zip(labellist,[i for i in wids.winfo_children() if isinstance(i, (tk.Entry,tk.Text))]):
if isinstance(k,tk.Entry):
cusdict[i] = k.get()
elif isinstance(k, tk.Text):
cusdict[i] = k.get(1.0,'end')
else:
pass
return cusdict
def super_del(self,wids):#删除entry和text类的内容
for wid in wids.winfo_children():
if isinstance(wid,tk.Text):
wid.delete(1.0,"end")
elif isinstance(wid, tk.Entry):
wid.delete(0,"end")
else:
pass
def super_insert(self,wids,text):#为entry或text类组件插入内容
ins=[i for i in wids.winfo_children() if isinstance(i, (tk.Entry,tk.Text))]
for wid,value in zip(ins,text):
wid.insert("end",value)
def creat_tree(self,wid,headers,height=4):#建立treeview组件
tree=ttk.Treeview(wid,columns=headers,show='headings',height=height)
for n,i in enumerate(headers):
tree.column(i,width=60,)
tree.heading(column=i,text=i)
sc=ttk.Scrollbar(wid,)
sc['command']=tree.yview
sc.pack(side='right',fill='both')
tree["yscrollcommand"]=sc.set
tree.pack(side="top",fill="both",expand=1)
return tree
def tree_insert(self,table,datas):#插入数值
# 插入数据
if datas:
for index, data in enumerate(datas):
table.insert('', index, values=data)
def tree_del(self,obj):#清除组件内内容
child=obj.get_children()
for i in child:
obj.delete(i)
def create_lf1_children(self,parent,):#为一下项目提供筛选,搜索选项
def change(event):
cominfo["values"]=self.newlabelsdict[com.get()]
cominfo.current(0)
com=ttk.Combobox(parent,values=tuple(self.newlabelsdict.keys()),state="readonly",)
com.pack(side="left",padx=2,pady=2)
com.current(0)
com.bind('<<ComboboxSelected>>', change)
cominfo=ttk.Combobox(parent,state="readonly",values=self.newlabelsdict[com.get()])
cominfo.pack(side="left",padx=2,pady=2)
cominfo.current(0)
e=ttk.Entry(parent,)
e.pack(side="left",expand=1,pady=1,padx=5,fill="x")
return com,cominfo,e
def start_find(self,arc,colname,e):#便捷函数,为以下项目提供支持
tablename, col = self.new_zh_col.get(arc,None),self.new_zh_col.get(colname,None)
self.lf2.config(text=arc)
headers=self.newlabelsdict.get(arc,None)
table=self.creat_tree(self.lf2,headers)
par=e.get()
sqldoc="SELECT * FROM {} WHERE {} LIKE '%{}%' ".format(tablename,col,par) if par else "SELECT * FROM {} ".format(tablename)
datas=self.find_data(sqldoc)
return table ,datas
def search(self):#查找数据
def find():
self.reset(self.lf2)
arc=com.get()
colname = cominfo.get()
table,datas=self.start_find(arc,colname,e)
self.tree_insert(table,datas)
com, cominfo, e= self.create_lf1_children(self.lf1, )
tk.Button(self.lf1,text="开始查找",command=find).pack(side="left",expand=0,padx=5,pady=2,)
def edit(self):#编辑数据
def tree_selected(event):
name=com.get()
value_e=event.widget.item(event.widget.selection()[0])['values']
self.reset(self.lf2)
self.newdict.get(name,None)(self.newlabelsdict[name])
self.super_insert(self.lf2,value_e)
def find():
self.reset(self.lf2)
arc=com.get()
colname = cominfo.get()
table,datas=self.start_find(arc,colname,e)
self.tree_insert(table,datas)
table.bind("<<TreeviewSelect>>", tree_selected)
com, cominfo, e = self.create_lf1_children(self.lf1, )
tk.Button(self.lf1,text="开始查找",command=find).pack(side="left",expand=0,padx=5,pady=2,)
def delete(self):
def tree_selected(event):
name=com.get()
value_e=event.widget.item(event.widget.selection()[0])['values']
flag=messagebox.askokcancel('爱之深恨之切',"女王大人,确定要放弃它嘛")
if flag:
sqldoc="DELETE FROM {} WHERE {} = '{}' ".format(self.new_zh_col.get(name,None),self.prmkey.get(name,None)[0],value_e[self.prmkey.get(name,None)[1]])
self.del_data(sqldoc)
find()
else:
pass
def find():
self.reset(self.lf2)
arc=com.get()
colname = cominfo.get()
table,datas=self.start_find(arc, cominfo, e)
self.tree_insert(table,datas)
table.bind("<<TreeviewSelect>>", tree_selected)
com, cominfo, e = self.create_lf1_children(self.lf1, )
tk.Button(self.lf1,text="开始查找",command=find).pack(side="left",expand=0,padx=5,pady=2,)
def export(self):#导出数据,存为csv文件
def ex():
cur = self.con.cursor()
file=os.path.join(os.getcwd(),"{}{}.csv".format("数据汇总",time.strftime(r"-%Y-%m-%d %H-%M",time.localtime()),))
print(file)
with open(file,"w",newline="") as dd:
wter=csv.writer(dd)
for i in self.newlabelsdict.keys():
sqldoc="SELECT * FROM {} ".format(self.new_zh_col.get(i,None))
cur.execute(sqldoc)
datas=cur.fetchall()
wter.writerow(self.newlabelsdict[i])
wter.writerows(datas)
wter.writerow("")
messagebox.showinfo("喜报","女王陛下,数据已导出完成\n存储位置{}".format(file))
def beifen():
t = Thread(target=ex)
t.run()
cur = self.con.cursor()
for i, k in self.newlabelsdict.items():
lf21=tk.LabelFrame(self.lf2,text=i,bg="Wheat")
lf21.pack(side="top",fill="both",expand=1,pady=1)
sqldoc="SELECT * FROM {} ".format(self.new_zh_col.get(i,None))
cur.execute(sqldoc)
datas=cur.fetchall()
tk.Label(lf21,text="{}数据总数: {}条".format(i,len(datas)),font=("bold",15),bg="Wheat").pack(side="top",expand=1,fill="x")
tk.Button(self.lf2,text="导出数据",command=beifen,width=15).pack(side="bottom",expand=0,padx=5,pady=2,)
def totale(self):
cur = self.con.cursor()
for i, k in self.newlabelsdict.items():
lf21=tk.LabelFrame(self.lf2,text=i)
lf21.pack(side="top",fill="both",expand=1,pady=1)
table=self.creat_tree(lf21,k)
sqldoc="SELECT * FROM {} ".format(self.new_zh_col.get(i,None))
cur.execute(sqldoc)
datas=cur.fetchall()
self.tree_insert(table,datas)
def regret(self):
def eat():
self.con.rollback()
messagebox.showinfo("回到从前","女王大人,我们再次回到了从前")
tk.Label(self.lf2,text="女王陛下,该吃药了!!",font=("bold",30,),bg="Wheat").pack(side="top",expand=1,fill="x")
tk.Button(self.lf2,text="立即嗑药",command=eat,width=15).pack(side="bottom",expand=0,padx=5,pady=2,)
if __name__ == "__main__":
if not os.path.exists("mydata"):
os.mkdir("mydata")
root = tk.Tk()
# root.option_add("*Font", "微软雅黑")
root.iconbitmap('crown.ico')
root.title("女王的宝库")
# root.attributes("-alpha", 0.9)透明度设置,奈何女神不需要
root.geometry("{}x{}+{}+{}".format(root.winfo_screenwidth()//2,root.winfo_screenheight()//2,root.winfo_screenwidth()//4,root.winfo_screenheight()//4))
app=App(root)
app.mainloop()
关于Python实现简易信息分类存储软件的介绍到此结束,更多相关内容请搜索本站历史文章或继续浏览后续内容,感谢支持。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













