你说的每一句我都记着,还带时间呢:简洁版纪念日
胡言
上一篇博客弄的纪念日界面本来打算不弄后端的了,但是想了想这算是最后一个tkinter程序吧,以后将不再更新这专栏的内容,当然对这专栏有兴趣的同学可以翻翻以前的博客,我记得应该有好几个小项目了,练习并用来熟悉语法足够了。
以后我将开一个算法专栏,不过我们不解难题,只解简单以及中等的题目(脑子不够用!!)。至于题目来源的话,一个文章我将分为两个板块:Leetcode以及Codewars,并且出于练习的目的,两个板块一个用python解一个用c++解,分享个人解法已经大神解法。
好了,回归主题,分享最后一篇小项目,简洁版纪念日。
整体
整体代码
main.py
# #!/usr/bin/env python
# # -*- coding: utf-8 -*-
# # @Time : 2020/02/27 12:21
# # @Author : Cxk
# # @File : main.pyimport os
from tkinter import *
from tkinter.messagebox import *
from tkinter import ttk # 导入ttk模块,因为下拉菜单控件在ttk中
from datetime import datetime
import threading
import webbrowser
from Ann_date_sql import *# from error import save_error
class Addpage(object):def __init__(self, master=None):self.root = master#master: 父容器。self.createPage()self.year=''self.month=''self.day=''def createPage(self):"""获得输入框内容进行保存进行容错处理,对于未输入的标题与日期提示用户进行更改"""def save():titles=self.titles.get()if self.year=='' or self.month=='' or self.day=='' or titles=='':showinfo(title='错误', message='标题或者日期不能为空!')else:date=self.year+'-'+self.month+'-'+self.daydate=str(datetime.strptime(date,"%Y-%m-%d")).split(' ')[0]#将字符串改为时间类型info=text.get('0.0', END)now_time=str(datetime.strptime(datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),"%Y-%m-%d-%H-%M-%S"))user_insertData(titles,date,info,now_time)showinfo(title='提示', message='纪念日保存成功,请重启软件生效!')self.page.destroy()self.root.destroy()self.page = Toplevel(self.root)self.page.title('添加纪念日') self.titles = StringVar()winWidth = 300winHeight = 350screenWidth = self.page.winfo_screenwidth()screenHeight = self.page.winfo_screenheight()x = int((screenWidth - winWidth) / 2)y = int((screenHeight - winHeight) / 2)# 设置窗口初始位置在屏幕居中self.page.geometry("%sx%s+%s+%s" % (winWidth, winHeight, x-351, y))# 设置窗口图标# root.iconbitmap("./image/icon.ico")# 设置窗口宽高固定self.page.resizable(0, 0)Label(self.page,font=("微软雅黑", 12),text="标题").place(x=132,y=0)Entry(self.page,textvariable=self.titles,width=10,bd=5).place(x=108,y=25)Label(self.page,font=("微软雅黑", 12),text="开始时间").place(x=120,y=55)# 创建下拉菜单cmb = ttk.Combobox(self.page,width=11,foreground='blue',background='blue')cmb.place(x=0,y=85)# 设置下拉菜单中的值cmb['value'] = ('点击选择年份...', '1900', '1901', '1902', '1903', '1904', '1905', '1906', '1907', '1908', '1909', '1910', '1911', '1912', '1913', '1914', '1915', '1916', '1917','1918', '1919', '1920', '1921', '1922', '1923', '1924', '1925', '1926', '1927','1928', '1929', '1930', '1931', '1932', '1933', '1934', '1935', '1936', '1937','1938', '1939', '1940', '1941', '1942', '1943', '1944', '1945', '1946', '1947','1948', '1949', '1950', '1951', '1952', '1953', '1954', '1955', '1956', '1957','1958', '1959', '1960', '1961', '1962', '1963', '1964', '1965', '1966', '1967', '1968', '1969', '1970', '1971', '1972', '1973', '1974', '1975', '1976', '1977', '1978', '1979', '1980', '1981', '1982', '1983', '1984', '1985', '1986', '1987','1988', '1989', '1990', '1991', '1992', '1993', '1994', '1995', '1996', '1997','1998', '1999', '2000', '2001', '2002', '2003', '2004', '2005', '2006', '2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016', '2017', '2018', '2019', '2020', '2021', '2022', '2023', '2024', '2025', '2026', '2027', '2028', '2029')# 设置默认值,即默认下拉框中的内容cmb.current(0)# 默认值中的内容为索引,从0开始# 执行函数def func(event):self.year=cmb.get()cmb.bind("<<ComboboxSelected>>",func)# 创建下拉菜单cmb1 = ttk.Combobox(self.page,width=11,foreground='blue',background='blue')cmb1.place(x=100,y=85)# 设置下拉菜单中的值cmb1['value'] = ('点击选择月份...', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12')# 设置默认值,即默认下拉框中的内容cmb1.current(0)# 默认值中的内容为索引,从0开始# 执行函数def func1(event):self.month=cmb1.get()cmb1.bind("<<ComboboxSelected>>",func1)# 创建下拉菜单cmb2 = ttk.Combobox(self.page,width=11,foreground='blue',background='blue')cmb2.place(x=200,y=85)# 设置下拉菜单中的值cmb2['value'] = ('点击选择日期...', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13','14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31')# 设置默认值,即默认下拉框中的内容cmb2.current(0)# 默认值中的内容为索引,从0开始# 执行函数def func2(event):self.day=cmb2.get()cmb2.bind("<<ComboboxSelected>>",func2)Label(self.page,font=("微软雅黑", 12),text="内容详情").place(x=120,y=110)text = Text(self.page,width=30, height=12)text.place(x=45,y=140)Button(self.page,text='保存', bd =5,width=10,command=save).place(x=110,y=310)class Infopage(object):def __init__(self, master=None):self.root = master#master: 父容器。self.createPage()def createPage(self):def del_ann(x):user_deldb(x)showinfo(title='提示', message='该纪念日已删除!请重启软件生效!')self.page.destroy()self.root.destroy()global titlessif titless=='暂无':showinfo(title='错误', message='暂无该纪念日!')else:self.page = Toplevel(self.root)self.page.title('纪念日详情') winWidth = 400winHeight = 400screenWidth = self.page.winfo_screenwidth()screenHeight = self.page.winfo_screenheight()x = int((screenWidth - winWidth) / 2)y = int((screenHeight - winHeight) / 2)# 设置窗口初始位置在屏幕居中self.page.geometry("%sx%s+%s+%s" % (winWidth, winHeight, x+401, y))# 设置窗口图标# root.iconbitmap("./image/icon.ico")# 设置窗口宽高固定self.page.resizable(0, 0)#根据标题查询数据库返回数据,获取标题,开始时间,内容。all_title=list(user_showdb(titless))title=all_title[1]start_day=all_title[2]#获取当前时间now_day=str(datetime.strptime(datetime.now().strftime('%Y-%m-%d'),"%Y-%m-%d")).split(' ')[0]#获得当前时间减去纪念日的开始时间的相差天数date=str(datetime.strptime(datetime.now().strftime('%Y-%m-%d'),"%Y-%m-%d")-datetime.strptime(start_day,"%Y-%m-%d")).split(',')[0]info=all_title[3]j=0infos=''#由于内容太长会超出窗口显示不美观,我们对内容进行处理,每10个字符进行换行for i in info:if j<=10:infos+=ij+=1else:infos+=i+'\n'j=0Label(self.page,font=("微软雅黑", 25),text=title).pack()Label(self.page,font=("微软雅黑", 10),text=start_day+"---"+now_day,fg = "red").pack()Label(self.page,font=("微软雅黑", 20),text=date,fg = "red").pack()Label(self.page,font=("微软雅黑", 15),text=infos).pack()Button(self.page,text='删除该纪念日', bd =5,width=10,command=lambda :del_ann(title)).pack(anchor=N)class Rootpage(object):def __init__(self, master=None):self.root = masterwinWidth = 400winHeight = 400screenWidth = self.root.winfo_screenwidth()screenHeight = self.root.winfo_screenheight()x = int((screenWidth - winWidth) / 2)y = int((screenHeight - winHeight) / 2)# 设置窗口初始位置在屏幕居中self.root.geometry("%sx%s+%s+%s" % (winWidth, winHeight, x, y))# 设置窗口图标# root.iconbitmap("./image/icon.ico")# 设置窗口宽高固定self.root.resizable(0, 0)self.createPage()def createPage(self):def fun():Addpage(self.root)def fun2(x):global titlesstitless=xInfopage(self.root)self.author_page = Frame(self.root) self.author_page.pack()def open_url(event):webbrowser.open("https://me.csdn.net/Cxk___", new=0)Label(self.author_page,font=("微软雅黑", 12),text="点击联系作者@Cxk").pack()link=Label(self.author_page,font=("微软雅黑", 12),fg='blue',text="CSDN博客@半盏清茶℡")link.pack()link.bind("<Button-1>", open_url)Button(root,text='+', bd =5,width=10,command=fun).place(x=160,y=55)#查询数据库所有的内容获得返回,由于我们的界面是要最新的4个纪念日,所以对于小于4个纪念日我们要进行处理#至于获得前4个最新的内容我们进行从后往前进行切片处理[-4:],代表从后往前切4个all_ann=user_slectTable()if all_ann==[]:Button(root,text='暂无纪念日信息', bd =5,width=20,height=5,command="#").place(x=130,y=150)else:if len(all_ann)==1:Button(root,text="%s\n%s\n%s\n%s"%(all_ann[0][1],all_ann[0][2],all_ann[0][3][0:10:],all_ann[0][4]), bd =5,width=20,height=5,command=lambda :fun2(all_ann[0][1])).place(x=125,y=150)if len(all_ann)==2:Button(root,text="%s\n%s\n%s\n%s"%(all_ann[1][1],all_ann[1][2],all_ann[1][3][0:10:],all_ann[1][4]), bd =5,width=20,height=5,command=lambda :fun2(all_ann[1][1])).place(x=125,y=100)Button(root,text="%s\n%s\n%s\n%s"%(all_ann[0][1],all_ann[0][2],all_ann[0][3][0:10:],all_ann[0][4]), bd =5,width=20,height=5,command=lambda :fun2(all_ann[0][1])).place(x=125,y=205)if len(all_ann)==3:all_ann.append(('0','暂无','暂无','暂无','暂无'))all_ann=all_ann[-4:]j=0for i in range(0,2):if i==0:Button(root,text="%s\n%s\n%s\n%s"%(all_ann[3][1],all_ann[3][2],all_ann[3][3][0:10:],all_ann[3][4]), bd =5,width=20,height=5,command=lambda :fun2(all_ann[3][1])).place(x=30+j,y=100)Button(root,text="%s\n%s\n%s\n%s"%(all_ann[1][1],all_ann[1][2],all_ann[1][3][0:10:],all_ann[1][4]), bd =5,width=20,height=5,command=lambda :fun2(all_ann[1][1])).place(x=30+j,y=205)else:Button(root,text="%s\n%s\n%s\n%s"%(all_ann[2][1],all_ann[2][2],all_ann[2][3][0:10:],all_ann[2][4]), bd =5,width=20,height=5,command=lambda :fun2(all_ann[2][1])).place(x=30+j,y=100)Button(root,text="%s\n%s\n%s\n%s"%(all_ann[0][1],all_ann[0][2],all_ann[0][3][0:10:],all_ann[0][4]), bd =5,width=20,height=5,command=lambda :fun2(all_ann[0][1])).place(x=30+j,y=205)j+=180else:all_ann=all_ann[-4:]j=0for i in range(0,2):if i==0:Button(root,text="%s\n%s\n%s\n%s"%(all_ann[3][1],all_ann[3][2],all_ann[3][3][0:10:],all_ann[3][4]), bd =5,width=20,height=5,command=lambda :fun2(all_ann[3][1])).place(x=30+j,y=100)Button(root,text="%s\n%s\n%s\n%s"%(all_ann[1][1],all_ann[1][2],all_ann[1][3][0:10:],all_ann[1][4]), bd =5,width=20,height=5,command=lambda :fun2(all_ann[1][1])).place(x=30+j,y=205)else:Button(root,text="%s\n%s\n%s\n%s"%(all_ann[2][1],all_ann[2][2],all_ann[2][3][0:10:],all_ann[2][4]), bd =5,width=20,height=5,command=lambda :fun2(all_ann[2][1])).place(x=30+j,y=100)Button(root,text="%s\n%s\n%s\n%s"%(all_ann[0][1],all_ann[0][2],all_ann[0][3][0:10:],all_ann[0][4]), bd =5,width=20,height=5,command=lambda :fun2(all_ann[0][1])).place(x=30+j,y=205)j+=180#获取菜单栏的标题展示返回的是title的列表,我们转换成元组b# 创建下拉菜单a=user_titledb()b=['点击查看更多...']for i in a:b.append(list(i)[0])b=tuple(b)cmb = ttk.Combobox(root,width=20,foreground='blue',background='blue')cmb.place(x=120,y=330)# 设置下拉菜单中的值cmb['value'] = b# 设置默认值,即默认下拉框中的内容cmb.current(0)# 默认值中的内容为索引,从0开始# 执行函数def func(event):global titlesstitless=cmb.get()Infopage(self.root)cmb.bind("<<ComboboxSelected>>",func)if __name__ == "__main__":global titlessroot = Tk() root.title('纪念日') Rootpage(root)root.mainloop()
数据库
# -*- coding:utf-8 -*-
import sqlite3# 打开数据库
def user_opendb():conn = sqlite3.connect("ann_date.db")cur = conn.execute("""create table if not exists ann_info(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,title varchar(128),start_time char(128),info varchar(256),add_time varchar(128))""")return cur,conn#查询全部信息
def user_slectTable():hel = user_opendb()cur = hel[1].cursor()cur.execute("select * from ann_info")res = cur.fetchall()#for line in res:#for h in line:#print(h),#print(line)return rescur.close()# 往数据库中添加内容
def user_insertData(title,start_time,info,add_time):hel = user_opendb()hel[1].execute("insert into ann_info(title,start_time,info,add_time)values (?,?,?,?)",(title,start_time,info,add_time))hel[1].commit()hel[1].close()#查询个人信息
def user_showdb(title):hel = user_opendb()cur = hel[1].cursor()cur.execute("select * from ann_info where title='%s'"%title)res = cur.fetchone()return rescur.close()# 删除数据库中的全部内容
def user_delalldb():hel = user_opendb() # 返回游标connhel[1].execute("delete from ann_info")print("删库跑路Cxk我最帅")hel[1].commit()hel[1].close()# 删除数据库中的指定内容
def user_deldb(title):hel = user_opendb() # 返回游标connhel[1].execute("delete from ann_info where title='%s'"%title)print("已删除标题为 %s 纪念日" %title)hel[1].commit()hel[1].close()# 修改数据库的内容
#def user_alter(title,start_time,info,add_time):
# hel = user_opendb()
# hel[1].execute("update ann_info set start_time=?, info= ?,add_time=? where title="+title,#(start_time,info,add_time))
# hel[1].commit()
# hel[1].close()#查询个人信息
def user_titledb():hel = user_opendb()cur = hel[1].cursor()cur.execute("select title from ann_info")res = cur.fetchall()return rescur.close()
要点处理
- 添加板块------获得输入框内容进行保存,进行容错处理,对于未输入的标题与日期提示用户进行更改,日期选择器上一篇博客有讲
- 展示模块------
#根据标题查询数据库返回数据,获取标题,开始时间,内容。all_title=list(user_showdb(titless))title=all_title[1]start_day=all_title[2]#获取当前时间now_day=str(datetime.strptime(datetime.now().strftime('%Y-%m-%d'),"%Y-%m-%d")).split(' ')[0]#获得当前时间减去纪念日的开始时间的相差天数date=str(datetime.strptime(datetime.now().strftime('%Y-%m-%d'),"%Y-%m-%d")-datetime.strptime(start_day,"%Y-%m-%d")).split(',')[0]info=all_title[3]j=0infos=''#由于内容太长会超出窗口显示不美观,我们对内容进行处理,每10个字符进行换行for i in info:if j<=10:infos+=ij+=1else:infos+=i+'\n'j=0
主页面-----
#查询数据库所有的内容获得返回,由于我们的界面是要最新的4个纪念日,所以对于小于4个纪念日我们要进行处理 #至于获得前4个最新的内容我们进行从后往前进行切片处理[-4:],代表从后往前切4个 all_ann=user_slectTable()
乱语
好了,应该没啥了,毕竟也仅仅有几处进行数据交互,每个页面的数据互通采用全局变量global titless来传递标题,然后获取数据库内容。资源已经上传了,懒得在本文复制的可以下载,设置了基础 1 积分。
你说的每一句我都记着,还带时间呢:简洁版纪念日相关推荐
- 三句话巧记 23 种设计模式
大家都知道 23 种设计模式,其中又可以分成三类,创建型模式,结构型模式,行为型模式.但是总是在实际应用中忘记了,当具体看到一些代码的时候也想不起来具体对应的是哪种设计模式,对经常重构的代码人员来说是 ...
- 三句话巧记23中设计模式
大家都知道23中设计模式,其中又可以分成三类,创建型模式,结构型模式,行为型模式.但是总是在实际应用中忘记了,当具体看到一些代码的时候也想不起来具体对应的是哪种设计模式,对经常重构的代码人员来说是一个 ...
- 10句撩人的英语情话带翻译 情人节给爱人不一样爱
情人节就要来了,想要给爱人带来不一样的爱,那就不妨试试英语情话吧,不仅有格调,感情表达也非常的直白.若是找不到适合的英语情话,就可以看看小编给大家带来的10句撩人的英语情话,每一句都还带翻译. 1.Y ...
- 域名是干啥用的?企业自己都记不住的域名还能发挥作用吗?
对于每一个从事数字化营销的企业来说,"域名"是一个再熟悉不过的词了. 随着互联网经济竞争的愈发激烈,以及营销方式的不断升级,域名也不再只局限于作为网站的"入口" ...
- x21能刷小米系统吗_小米系统是安卓系统中最强的吗?大家都错了,它是MIUI的进化版...
小米系统是安卓系统中最强的吗?大家都错了,它是MIUI的进化版 现在国产手机做得越来越好了,在硬件方面国产手机比同级别的外国品牌要厚道太多了,所以在中国,外国品牌是没有任何生存空间的.在性价比方面他们 ...
- 不逼自己一把都不知道自己还能这么优秀(小鹅通学习记录大批量队列同步)
不逼自己一把都不知道自己还能这么优秀-小鹅通学习记录大批量队列同步实战日志 前言 一.编程语言介绍 1.php是世界上最好的语言 2.第三方API对接的苦恼 3.为什么说好的项目进度表都是画饼 二.炫 ...
- 每句话都可以品半辈子!!!
1.风之所以寂寞,皆因他吹落了花.与其给鱼一双翅膀,不如还鱼一池水塘! 2.疲惫的不是脚步,而是心情!失败的不是结果,而是意志! 3.你是秋天里的风,我却是一片叶.当你来到我的身边,我跟随着你.而你不 ...
- 每句话都可以品味一生
1,老鼠嘲笑猫的时候,身旁必有一个洞. 2,站在山顶和站在山脚下的两人,虽然地位不同,但在对方眼里,同样的渺小. 3,结论就是你懒得再想下去的地方.――路的尽头,仍然是路,只要你愿意走. 4,使我们不 ...
- 你轻轻哼唱一句,都是最美的一首歌
近日,来自香港科技大学的学生研发出一款名为UMix的App,只要是人声哼出的歌声,UMix App会转化为MIDI(乐器数码界面)格式音乐,再透过附带的十多种乐器转换方式,便变成一首悦耳的乐曲. 说起 ...
最新文章
- 超越EfficientNet,GPU上加速5倍,何恺明组CVPR 2020论文提出新型网络设计范式
- SpringBoot如何使用策略模式干掉if else
- 简单快速开发C\S架构程序用最简单的不分层最快的效率达到功能要求的例子程序FrmKnowledge日积月累功能的实现...
- 网络营销重点之如何了解用户需求完善网络营销策略
- vue配置vue-router
- 在redhat6.3 安装oracle 11.2.0.1遇到的错误
- python中curve fit_在python中拟合多变量curve_fit
- ifix如何设画面大小_如何让你的视频又小又清晰?视频编码输出软件来了
- React hook 中的数据获取
- 当物联网遇上云原生:K8s向边缘计算渗透中
- Linux 命令(129)—— passwd 命令
- (int),Int32.Parse,Convert.ToInt3…
- Matlab中Fatal Error On Startup
- cobalt strik启动
- 移动端可以查看的设计APP,推荐给大家
- 撤销commit操作
- iOS 关于自定义转场动画,以UITabBarController为例
- 关于windows server 2016服务器 exchange 2010 managment Shell 停止工作的问题(已解决)
- 统计git代码行数和本地代码行数的方法
- 音乐API调用以及分析(以酷狗音乐为例)