你說的每一句我都記着,還帶時間呢:簡潔版紀念日

胡言

上一篇博客弄的紀念日界面本來打算不弄後端的了,但是想了想這算是最後一個tkinter程序吧,以後將不再更新這專欄的內容,當然對這專欄有興趣的同學可以翻翻以前的博客,我記得應該有好幾個小項目了,練習並用來熟悉語法足夠了。

以後我將開一個算法專欄,不過我們不解難題,只解簡單以及中等的題目(腦子不夠用!!)。至於題目來源的話,一個文章我將分爲兩個板塊:Leetcode以及Codewars,並且出於練習的目的,兩個板塊一個用python解一個用c++解,分享個人解法已經大神解法。

好了,迴歸主題,分享最後一篇小項目,簡潔版紀念日。

整體

 

整體代碼

main.py

# #!/usr/bin/env python
# # -*- coding: utf-8 -*-
# # @Time    : 2020/02/27 12:21
# # @Author  : Cxk
# # @File    : main.py

import 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.day
                date=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 = 300
        winHeight = 350
        screenWidth = 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 titless
        if titless=='暫無':
            showinfo(title='錯誤', message='暫無該紀念日!')
        else:
            self.page = Toplevel(self.root)
            self.page.title('紀念日詳情') 
            winWidth = 400
            winHeight = 400
            screenWidth = 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=0
            infos=''
            #由於內容太長會超出窗口顯示不美觀,我們對內容進行處理,每10個字符進行換行
            for i in info:
                if j<=10:
                    infos+=i
                    j+=1
                else:
                    infos+=i+'\n'
                    j=0

            Label(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 = master
        winWidth = 400
        winHeight = 400
        screenWidth = 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 titless
            titless=x
            Infopage(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=0
                for 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
            else:
                all_ann=all_ann[-4:]
                j=0
                for 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 titless
            titless=cmb.get()
            Infopage(self.root)
        cmb.bind("<<ComboboxSelected>>",func)
        
if __name__ == "__main__":
    global titless
    root = 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 res
        cur.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 res
        cur.close()
        
    
#   刪除數據庫中的全部內容
def user_delalldb():
        hel = user_opendb()              # 返回遊標conn
        hel[1].execute("delete from ann_info")
        print("刪庫跑路Cxk我最帥")
        hel[1].commit()
        hel[1].close()
        
#   刪除數據庫中的指定內容
def user_deldb(title):
        hel = user_opendb()              # 返回遊標conn
        hel[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 res
        cur.close()

要點處理

  1. 添加板塊------獲得輸入框內容進行保存,進行容錯處理,對於未輸入的標題與日期提示用戶進行更改,日期選擇器上一篇博客有講
  2. 展示模塊------
    #根據標題查詢數據庫返回數據,獲取標題,開始時間,內容。
                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=0
                infos=''
                #由於內容太長會超出窗口顯示不美觀,我們對內容進行處理,每10個字符進行換行
                for i in info:
                    if j<=10:
                        infos+=i
                        j+=1
                    else:
                        infos+=i+'\n'
                        j=0
    

     

  3. 主頁面-----

    #查詢數據庫所有的內容獲得返回,由於我們的界面是要最新的4個紀念日,所以對於小於4個紀念日我們要進行處理
    #至於獲得前4個最新的內容我們進行從後往前進行切片處理[-4:],代表從後往前切4個
    all_ann=user_slectTable()

     

     

 

亂語

好了,應該沒啥了,畢竟也僅僅有幾處進行數據交互,每個頁面的數據互通採用全局變量global titless來傳遞標題,然後獲取數據庫內容。資源已經上傳了,懶得在本文複製的可以下載,設置了基礎 1 積分。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章