首页 > 解决方案 > 不断检查时间列表和当前时间并显示通知

问题描述

我目前正在开发一个 python 待办事项应用程序。所有用户创建的事件都存储在名为 toDoEvents 的字典中,其中包含标题、到期时间、提醒时间和描述。现在我正在开发一个使用 toast 的通知系统。我需要不断检查每个事件的提醒日期列表,如果它与当前时间匹配,则调用 toast 通知。

我想做这样的事情,除了每次分钟变化时不断检查它:

from win10toast import ToastNotifier
import time
from datetime import datetime
from PyQt5.QtCore import QDateTime

toDoEvents = {}
class TodoEvent:

    def __init__(self, title, due_time, remind_time, description):
        self.title = title
        self.due_time = due_time
        self.remind_time = remind_time
        self.description = description
        toDoEvents[self.title] = self

    def change_title(self, new_title):
        self.title = new_title

    def change_due_time(self, new_due_time):
        self.due_time = new_due_time

    def change_remind_time(self, new_remind_time):
        self.remind_time = new_remind_time

    def change_description(self, new_description):
        self.description = new_description


event1 = TodoEvent("test", QDateTime(2019, 10, 26, 1, 18).toPyDateTime(), QDateTime(2019, 10, 26, 1, 18).toPyDateTime(), "test description")

for event in toDoEvents.values():

    if event.remind_time.strftime("%m/%d/%Y, %H:%M") == datetime.now().strftime("%m/%d/%Y, %I:%M"):
        toaster = ToastNotifier()
        toaster.show_toast(event.title, event.description, threaded=True, icon_path=None, duration=8)
        while toaster.notification_active():
            time.sleep(0.1)

最有效的方法是什么?编辑:希望在每分钟更改时执行代码,而不是每 60 秒执行一次(假设用户在 0 秒处启动程序)

标签: pythonpython-3.xpyqt5toast

解决方案


事实上,我正在编写几乎相同类型的程序,我建议使用QTimer而不是不断检查当前时间。无论如何,由于 QTimer 默认计时有 5% 的间隔余量(对于长间隔可能非常高),您可能希望将其timerType设置为Qt.PreciseTimer.

class TodoEvent:

    def __init__(self, title, due_time, remind_time, description):
        self.title = title
        self.due_time = due_time
        self.remind_time = remind_time
        self.description = description
        toDoEvents[self.title] = self
        self.timer = QTimer(self)
        self.timer.setSingleShot(True)
        self.timer.timeout.connect(self.showReminder)
        self.timer.setTimerType(Qt.PreciseTimer)
        self.change_remind_time(remind_time)

    def change_title(self, new_title):
        self.title = new_title

    def change_due_time(self, new_due_time):
        self.due_time = new_due_time

    def change_remind_time(self, new_remind_time):
        self.remind_time = new_remind_time
        self.timer.start(QDateTime.currentDateTime().msecsTo(self.remind_time))

    def change_description(self, new_description):
        self.description = new_description

    def showReminder(self):
        toaster = ToastNotifier()
        toaster.show_toast(self.title, self.description, threaded=True, icon_path=None, duration=8)

event1 = TodoEvent("test", 
                   QDateTime(2019, 10, 26, 1, 18), 
                   QDateTime(2019, 10, 26, 1, 18), 
                   "test description")

请注意,QTimer 间隔以毫秒为单位表示为integer,因此日期间隔可能会出现问题,高于 32 位整数的最大值。标准整数的最大正值是 2147483647,当提到毫秒时,它是 24 天、20 小时、31 分钟、23 秒和 647 毫秒。

这意味着,如果您因某个日期的毫秒间隔高于该值而收到提醒,您将获得一个无效的计时器(间隔等于 -1)。
虽然普通人不太可能将他/她的计算机保持开启这么长时间,但这并非不可能(想想经常运行数周而不重新启动的便携式设备),因此您可能需要添加一个检查到期时间的功能对于太高的间隔,并最终添加另一个计时器,该计时器将“恢复”自身,直到间隔变为有效,然后启动通知的实际计时器。


推荐阅读