【问题标题】:notify after x number of days even when the program is closed between the days即使程序在这几天之间关闭,也会在 x 天后通知
【发布时间】:2018-03-29 08:46:37
【问题描述】:
from tkinter import *
from datetime import datetime, timedelta 
import pickle
from tkinter import messagebox

filename = "file.pk" #filename data stored as dic = {time:[name,item]}

root = Tk()

t = IntVar()
i = StringVar()
n = StringVar()


def Notification_On_Completing(n, i, t):
    return messagebox.showinfo("Completed", "Name:- {}, Item:-{}, in Days:-{}".format(n, i, t)) 


def Check_If_Time_Is_Over():   #my actual problem is in this function 

    with open(filename, "rb") as f: 
        dic = pickle.load(f)

    now = datetime.now()

    for i, j in dic: #trying to loop and check if the time == now() 
            if i == now: 
                Notification_On_Completing(j[0], j[1], i) #if its true return the key which is equal with its value

            elif i != now: #if now time i am tryinng to show how much time left
                print(i - now, "Time has left for name:-{}, item:-{}".format(j[0],j[1]))
            else:
                root.after(10000, Check_If_Time_Is_Over)

def SaveTheDaysToNotify():

    now = datetime.now()
    time = t.get()  # days to wait beforer notifying
    item = i.get()  #item name    
    name = i.get()  #name 

    end = now + timedelta(days=time)  #adding today with the number of days to notify

    with open(filename.pk, "rb") as f: # avoiding the overide of the files
        dic = pickle.load(f)

    dic= {end:[name, item]}  # saving a days to notify as dic which will also show the name , and item
    with open("file.pk", "wb") as f: #keeping record of the time time to notify
        pickle.dump(dic, f)
    Check_If_Time_Is_Over()


#Gui starts from here

time1 = Entry(root,textvariable=t).pack()  #taking entry as of time, name and item
name1 = Entry(root,textvariable=n).pack()

item1 = Entry(root, textvariable=i).pack()

ss = Button(root,text="done",command=SaveTheDaysToNotify).pack() #以字典格式添加到pickle数据库 dic ={time:[name, item]}

root.mainloop() Check_If_Time_Is_Over()

我正在尝试制作一个程序,它将条目作为时间,项目,名称。时间将被视为显示通知的天数。例如,程序应在 x 天后显示通知并不断检查是否x 天已经到来,即使该程序将在几天或几小时间隔内关闭并重新打开某些时间。

【问题讨论】:

  • 你需要某种外部存储,很明显。
  • 你用泡菜储存
  • 你能建议我任何解决方案

标签: python-3.x datetime tkinter notifications


【解决方案1】:

您可以将输入的日期以及数字存储在文件中。您可以使用datetime.timedelta 为您的时间添加天数。

每次你的程序运行时,你检查这个特殊文件是否存在,读取日期和数字,检查 date+number_days 是今天还是今天之前,然后创建你的通知。

如果您的程序不是 startet,它不会显示任何内容。如果您的程序没有在两者之间关闭,它不会显示任何内容 - 后一种情况可以通过一些计时器来完成,并在 TKs 主循环内定期检查(记住小时,如果更改,再次检查文件或...)

例子:

import os

from datetime import datetime , timedelta

fn = "myfile.txt"
date = None
days = None

def delDateFile():
    """Remove date file after showing notification, so next time user will
    be asked to input days again."""
    os.remove(fn)

def writeDate(d:int):
    """Adds d days to now(), writes it to file and returns the date."""
    date = datetime.now()  + timedelta(days = d)
    with open(fn,"w") as f: # overwriting existing file
        f.write(stringFromDate(date ))
    return date.date()

def dateFromString(s):
    """Parses a string into a date. Format: '%Y-%m-%d'"""
    try:
         return datetime.strptime(s,'%Y-%m-%d').date()
    except ValueError:
        print("Malformed date")
        return writeDate(-1)        

def stringFromDate(d):
    """Makes a string from a date. Format: '%Y-%m-%d'"""
    return datetime.strftime(datetime.now(),'%Y-%m-%d')


def needToShowNotification():
    def checkIfFileExistsAndExtractDate():
        """Reads a date from file, returns date from file or None if no file exists."""
        if os.path.exists(fn):
            with open(fn,"r") as f:
                date = dateFromString(f.readline())
            return date 
        return None

    def askForDaysAndWriteFile():
        """Asks for days and writes a file with the new date. Malformed input produces date of yesterday"""
        try:
            days = int(input("Days? "))
        except (ValueError, EOFError): # malformed input: empty or no number
            days = -1

        return writeDate(days) 


    # prefer date from file, else ask and write file
    date = checkIfFileExistsAndExtractDate() or askForDaysAndWriteFile()

    return date < datetime.now().date()


def Notif():
    print("------------------")
    print("-- NOTIFICATION --")
    print("------------------")
    delDateFile()

if needToShowNotification():
    Notif()
else:
    print("Go ahead, no need to notify")

输入负数运行它以查看通知(或删除创建的文件)

【讨论】:

  • 我希望它每秒检查一次,如果它是我想要的那一天.....我该怎么做以及如何显示从开始到结束的倒计时的实时计时器
  • @HEalikTamu 为什么需要每秒检查一次?天仅每 24*60*60 秒切换一次……如果您只想创建一个“时钟”,请搜索它 - 并找到 f.e.:how-to-create-a-timer-using-tkinter
  • no if the time != now 那么我希望它实时显示 tkinter 还剩多少时间 ....plz 我需要一些帮助
  • 我想要的是如果时间 != now 那么它应该在 tkinter plz help 中打印剩余时间
  • @HEalikTamu 查看我在上面链接的how-to-create-a-timer 的答案。他们都使用 Tk 和计时器创建时钟 - 修改这些解决方案以不显示当前时间,而是显示 datetime.now().time() 和您的目标日期时间 0:0:0(或您想要的任何时间)之间的增量时间。他们还为您提供了如何使用 .after() 的示例,展示了如何激活计时器。自己想办法,这样比我编写代码时学到的更多。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多