Я добавляю еще один ответ, так как обновление вопроса сделало его немного не по теме, но я предпочитаю оставить его там, так как считаю, что это может быть полезно для других, даже если оно немного не связано с темой. в зависимости от обстоятельств.
Пример ниже подклассов QTimer делает это таймером, который изменяет только "таймауты" в минуту. Это может показаться немного сложным, но это связано с природой QTimers, которая может быть не такой точной, как можно было бы ожидать (как большинство таймеров);тем не менее, это позволяет улучшить реализацию, избегая ненужных излучений времени ожидания, так как иногда сигнал времени ожидания может излучаться за до конца минуты, таким образом испуская его снова, когда минута действительно меняется.
singleShot
настройка на самом деле не требуется, так как таймер будет перезапущен в любом случае с правильным интервалом (требуются постоянные проверки, так как в это время может произойти какой-то тяжелый рабочий процесс, приводящий к переключению таймера после изменения минут). Я только добавил это, поскольку я думаю , что это может немного улучшить производительность в случае большого количества таймеров, но я могу ошибаться. В любом случае, он будет работать в любом случае, даже без него.
class MinuteTimer(QTimer):
customTimeout = pyqtSignal()
def __init__(self, parent=None):
super(MinuteTimer, self).__init__(parent)
self.setSingleShot(True)
# default timer is CoarseTimer, which *could* fire up before, making it
# possible that the timeout is called twice
self.setTimerType(Qt.PreciseTimer)
# to avoid unintentional disconnection (as disconnect() without
# arguments disconnects the signal from *all* slots it's connected
# to), we "overwrite" the internal timeout signal attribute name by
# by switching it with our customTimeout signal instead, keeping
# its consistency with QTimer objects, at least by object naming
self._internalTimeout = self.timeout
self._internalTimeout.connect(self.startAdjusted)
self._internalTimeout.connect(self.customTimeout)
self.timeout = self.customTimeout
def start(self):
now = QTime.currentTime()
nextMinute = QTime(now.hour(), now.minute()).addSecs(60)
# if the next minute happens at or after the midnight of the day
# after (in this specific case, when "now" is at 23:59), msecsTo()
# will return a negative value, since QTime has no date reference:
# 14:30:00 to 14:29:00 is -60 seconds, so 23:59:00 to 00:00:00 is
# -86340 seconds; using the % modulus operator against the
# millisecond count in a day can give us the correct positive
# difference that can be used as an interval for QTimer
QTimer.start(self, now.msecsTo(nextMinute) % 86400000)
def startAdjusted(self):
now = QTime.currentTime()
# even when using a PreciseTimer, it is possible that the timeout
# is called before the minute change; if that's the case, we
# add 2 minutes, just to be "better safe than sorry"
addSecs = 120 if now.second() > 50 else 60
nextMinute = QTime(now.hour(), now.minute()).addSecs(addSecs)
QTimer.start(self, now.msecsTo(nextMinute) % 86400000)
def minuteEvent():
print('minute changed!')
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)
if __name__ == '__main__':
app = QApplication(sys.argv)
minuteTimer = MinuteTimer()
minuteTimer.timeout.connect(minuteEvent)
minuteTimer.start()
sys.exit(app.exec_())
Очевидно, что таймер может излучать свой сигнал до изменения минут (что приводит к неудачному уведомлению, если следующий сигнал испускается после егонезначительное изменение), но это в основном связано с вашей реализацией, и я считаю, что вам нужно проверить диапазон времени, чтобы убедиться, что каждый todo перехватывается, когда это должно быть.
В качестве возможной альтернативы вы можете испустить сигналс ожидаемым временем «ЧЧ: мм» (используя операторы, подобные addSecs = 120 if now.second() > 50 else 60
, который я использовал), а затем проверьте фактическое время напоминания.