Напоминалка для Windows, которая живёт в трее и не даёт забыть о делах. Тёмная тема, повторяющиеся напоминания, откладывание, ничего лишнего.
Версия 2.6 · Python + PySide6 · Windows 10/11
Оформление
- тёмная и светлая темы, плюс «как в системе» — переключается на лету
- контраст проверен по WCAG AA (основной текст 14.7:1 на светлой)
Три вкладки
- Активные — что ещё впереди, с группировкой по дням
- Требуют внимания — что сработало и ждёт решения
- Архив — выполненное. Нажал «Сделано» случайно? Кнопка «Вернуть»
Организация
- метки (Работа, Здоровье, Дом, Музыка или свои) — каждая своим цветом
- поиск по тексту и метке, фильтр по метке
- заготовки: сохрани настроенную форму и подставляй одной кнопкой
- горячие клавиши, в том числе глобальная — работает при свёрнутом окне
Напоминания
- разовые и повторяющиеся: каждый день, каждую неделю, каждый месяц
- график «каждые N часов в окне»: например, каждые 3 часа с 9:00 до 21:00 — после конца окна сигналы прекращаются и возобновляются на следующий день
- по выбранным дням недели — пн/ср/пт, будни, выходные
- предупреждение заранее: «за 30 минут до» приходит отдельным сигналом
- быстрые кнопки:
+15 мин,+1 час,+3 часа,Завтра 9:00,Вечером 19:00 - подсказка под формой: «Вт, чт в 19:00 · ближайшее через 1 день»
- редактирование готового напоминания — двойной клик по строке
- список сгруппирован по дням: Сегодня / Завтра / Пятница / 10.09.2026
- вкладки со счётчиками: «Активные (3)» и «Требуют внимания (1)»
Когда сработало
- окно со всеми сработавшими сразу, а не только с последним
- кнопки прямо в окне: «Сделано», «Отложить 10 мин», «Отложить на…»
- окно не блокирует программу — таймер продолжает работать
- всплывающее сообщение в трее и звук (можно отключить или заменить свой
.wav)
Трей
- ближайшее напоминание видно прямо в меню и в подсказке при наведении
- «Новое напоминание…» — создать, не открывая главное окно
- «Ближайшие» — подменю со следующими семью
- «Настройки…» — всё в одном месте
- одиночный клик по значку сворачивает и разворачивает окно
Настройки
- запуск вместе с Windows
- запускаться свёрнутым в трей
- крестик сворачивает в трей, а не закрывает
- окно поверх всех окон, всплывашка в трее, звук — по отдельности
- свой звуковой файл
- на сколько откладывает кнопка «Отложить»
- кнопка «Открыть папку с данными»
- Скачай папку с проектом.
- Запусти
Запусти меня.bat— он сам поставит зависимости и соберёт.exe. - Готовый файл появится в
dist\Умные Памятки.exe, ярлык — на рабочем столе.
Почему сборка в двух файлах.
Запусти меня.batнаписан только латиницей и умеет ровно одно: найти Python и передать управлениеbuild.py. Так сделано намеренно.cmd.exeчитает батник в текущей кодовой странице консоли, а она у всех разная — 866, 1251 или 65001. Русский текст внутри.batпри несовпадении превращается в мусор, а обрывки строк выполняются как команды ('ключаем' is not recognized...). Обойти это надёжно нельзя:chcpв начале файла не спасает, потому что cmd уже начал читать файл. Python 3.6+ печатает в консоль через Unicode-API, поэтому все русские сообщения о сборке выводитbuild.py— и они читаются при любых настройках системы.
Нужен установленный Python 3.9+.
При установке обязательно поставь галочку «Add Python to PATH», иначе .bat не найдёт Python.
pip install PySide6
python adaptive_reminder.py%APPDATA%\AdaptiveReminder\
├── reminders.json активные напоминания
├── missed_reminders.json те, что требуют внимания
└── settings.json настройки
Открыть эту папку можно кнопкой в настройках.
Данные не лежат рядом с программой — это важно. Если положить их в папку с .exe,
то при запуске из автозагрузки Windows рабочей папкой окажется C:\Windows\System32,
и напоминания «пропадут». Файлы из старой версии переносятся автоматически при первом запуске.
Запись атомарная (через временный файл), так что выключение света посреди сохранения
не оставит обрезанный JSON. Если файл всё-таки окажется битым, он не затирается,
а сохраняется как reminders.json.bad — данные можно достать руками.
| Файл | Что это |
|---|---|
adaptive_reminder.py |
всё приложение |
tests/ |
тесты, обычному пользователю не нужны (в .gitignore) |
Запусти меня.bat |
запускалка сборки, только латиница (см. выше) |
build.py |
сама сборка .exe, проверки и ярлык |
icon.ico |
иконка окна и трея |
notification.wav |
звук уведомления |
_test_v2.py |
тесты логики: расписание, склонения, файлы |
_test_v21.py |
тесты дней недели и предупреждений |
_test_v22.py |
тесты меток, заготовок, горячих клавиш, времени |
_test_v23.py |
тесты архива, свёрнутой формы, стрелок |
_test_v24.py |
тесты вёрстки: наложения, отступы, иконки |
_test_v25.py |
тесты диалогов, клавиш, светлой темы, контраста |
_test_v26.py |
тесты графика повторов и контраста меток |
_test_ui.py |
тесты интерфейса: трей, окна, редактирование |
_winstub/ |
заглушки winsound и winreg для запуска на Linux |
Reminder— одно напоминание (текст, время, тип повтора)ReminderManager— вся логика: загрузка, сохранение, расписание, проверка срабатыванийSettings— настройки в JSONWindowsStartupManager— автозагрузка через реестрAdaptiveReminderApp— главное окно и трейNotificationWindow,SnoozeDialog,QuickAddDialog,SettingsDialog— окна
Логика отделена от интерфейса: ReminderManager ничего не знает про Qt-виджеты
и тестируется без запуска окон.
python tests/_test_v2.py # логика, 32 проверки
python tests/_test_v21.py # дни недели и предупреждения, 28 проверок
python tests/_test_v22.py # метки, заготовки, клавиши, время, 44 проверки
python tests/_test_v23.py # архив, форма, стрелки, ярлык, 40 проверок
python tests/_test_v24.py # вёрстка и оформление, 40 проверок
python tests/_test_v25.py # диалоги, клавиши, темы, 45 проверок
python tests/_test_v26.py # график повторов, контраст, 47 проверок
python tests/_test_ui.py # интерфейс, 26 проверокНа Linux интерфейсные тесты запускаются через xvfb-run -a python _test_ui.py.
Проверяется в том числе:
- склонения: «1 минуту», «22 часа», «1 час 30 минут»
- месячные напоминания: 31 января → 28 февраля → 31 марта (число возвращается)
- ежедневные не уползают по времени суток после многих срабатываний
- все сработавшие возвращаются, а не только последнее
- битый JSON не роняет программу и не затирается
- путь к данным не зависит от рабочей папки
Исправлено
- данные переехали в
%APPDATA%— раньше при запуске из автозагрузки терялись - показываются все сработавшие напоминания; было
triggered[-1], то есть из трёх видно одно - окно уведомления больше не блокирует программу (был
QMessageBox.exec()) - пропущенные повторяющиеся попадают в список; раньше молча уезжали на следующий день
- месячные не застревали: было 31.01 → 28.02 → 28.03 → 28.04 навсегда
- ежедневные считаются от исходного времени и не сползают
- склонения: было «1 минут», «21 минут», «22 часов»
- «Отложить на 0 минут» больше не срабатывает мгновенно
- убрана рамка вокруг каждой подписи:
QLabelнаследуется отQFrame, и стильQFrame{...}цеплялся ко всем надписям - жёсткий индекс
tray_menu.actions()[1]в переключателе автозагрузки - константа
REG_VALUE_NAMEобъявлялась, но не использовалась - атомарная запись файлов, битый JSON откладывается в
.bad - вторая копия программы больше не запускается
Добавлено
- создание напоминания и настройки прямо из трея
- ближайшее напоминание в меню трея и в подсказке
- редактирование существующих напоминаний
- окно настроек
- вкладки вместо трёх секций подряд — окно стало компактнее
- выбор своего звука, отключение звука и всплывашек
- «Открыть папку с данными»
| Сочетание | Что делает |
|---|---|
Ctrl+Alt+N |
создать напоминание, даже когда окно свёрнуто (меняется в настройках) |
Ctrl+N |
перейти к полю текста |
Ctrl+Enter |
создать / сохранить |
Ctrl+E |
изменить выбранное |
Ctrl+F |
перейти к поиску |
Ctrl+1 / Ctrl+2 / Ctrl+3 |
вкладки: активные, требуют внимания, архив |
Delete |
удалить выбранное (когда фокус в списке) |
Ctrl+D |
удалить выбранное |
Esc |
отменить правку, очистить поиск или свернуть окно |
F5 |
обновить списки |
Ctrl+, |
настройки |
График повторов
- новый режим «Каждые N часов в окне»: шаг от 1 минуты до суток, начало и конец окна, при желании — только по выбранным дням недели
- шаги отсчитываются от начала окна, поэтому время не уползает
- работает и с окном через полночь (например, с 22:00 до 06:00)
- под формой сразу написано, сколько сигналов выйдет за день
Читаемость светлой темы
- цвета меток были подобраны под тёмный фон: на светлом 7 из 8 давали контраст ниже нормы (светло-зелёный — 1.8 при норме 4.5). Теперь два набора цветов, по одному на каждую тему
- приглушённый текст стал темнее: было 4.6, стало 6.5
- акцентные цвета доведены до нормы WCAG AA на всех трёх фонах
Мелочи
- треугольник у «Подробнее» больше не «плывёт»: это был текстовый символ ▾, который шрифт рисует со своей базовой линией. Заменён на иконку
Починено
- при открытии настроек сам собой выскакивал проводник выбора звука.
Причина: у кнопок в
QDialogвключёнautoDefault, и Enter в любом поле нажимал первую из них — а первой была «Выбрать…». ТеперьautoDefaultснят у всех кнопок, главной назначена «Сохранить» - звук по умолчанию виден: в поле написано «По умолчанию: notification.wav», рядом кнопка «▶» — послушать
- горячие клавиши заработали:
QActionне срабатывал, когда фокус был в поле ввода. Переведено наQShortcutс контекстом окна - вкладки больше не налезают на кнопку «Создать»: содержимое обёрнуто в прокрутку, и если окно не помещается на экран, появляется полоса, а не каша из виджетов
Оформление
- светлая тема и режим «как в системе» (читает настройку Windows)
- блок «Подробнее» — отдельная панель с отступами, а не поля впритык
- диалог «Как запомнить время» переделан: варианты стали карточками с пояснениями, выбранная подсвечивается рамкой
Починена вёрстка
- виджеты налезали друг на друга при переключении на «Архив». Причина: сумма минимальных высот (шапка + форма + вкладки) превышала высоту окна, а Qt в такой ситуации не добавляет прокрутку, а просто накладывает элементы. Теперь форма фиксирует свою высоту, окно поднимает минимум под содержимое, а все вкладки одинаковой высоты — окно не «прыгает»
- блок «Подробнее» перестроен с рядов на сетку
QGridLayout: поля больше не толкаются и выровнены по колонкам - у всех полей и кнопок одна высота, отступы кратны 4 px (8pt-сетка)
Настройки в окне
- шестерёнка в шапке. Раньше настройки были только в трее, хотя люди ищут их в самом окне
Горячие клавиши заработали
Ctrl+Alt+Nмолчал: PySide6 передаёт вnativeEventFilterобъект PyCapsule, а код делалint(message)— это падало, исключение проглатывалось. Добавлен разбор черезPyCapsule_GetPointer, заданыargtypesдляRegisterHotKey, код ошибки пишется в лог
Оформление
- четыре уровня поверхностей (surface elevation): чем ближе элемент к пользователю, тем светлее фон — глубина читается без теней, которые на тёмной теме почти не видны
- вкладки-подчёркивания вместо «папок»
- галочка в чекбоксе рисуется картинкой, как и стрелки списков
- списки лежат на «утопленной» поверхности без двойной рамки
Интерфейс проще
- форма свёрнута: наверху только «о чём» и «когда», остальное под «Подробнее». Принцип progressive disclosure — не показывать сразу всё, чем человек пользуется раз в неделю
- нижняя строка состояния убрана: теперь короткая плашка всплывает после действия и сама исчезает
- у выпадающих списков появилась видимая стрелка. Раньше её рисовал border-хак, который на Windows показывался квадратом
- правый клик по строке списка — то же меню, что и кнопками
Архив
- «Сделано» больше не стирает запись, а кладёт в архив (хранится 200 последних)
- «Вернуть» возвращает обратно, «Повторить» создаёт такое же заново
- «Убрать все» тоже отправляет в архив, а не в никуда
Починено
- имя ярлыка на рабочем столе превращалось в «пшфрывгшпфшгвыарфгышаргш»:
скрипт создания писался в UTF-16, а
cscriptчитал его как ANSI. Теперь PowerShell и UTF-8 с BOM — без BOM PowerShell 5.1 тоже читает файл как ANSI - тесты переехали в
tests/и добавлены в.gitignore
- исправлено время: напоминание на 14:40 срабатывало в 14:41. Поле ввода показывает только часы и минуты, но внутри хранило ещё и секунды от момента открытия формы — до 59 лишних секунд. Теперь секунды обнуляются и в форме, и в самом менеджере
- метки с цветовой раскраской, поиск и фильтр
- заготовки напоминаний: сохранить форму и подставлять одной кнопкой
- глобальная и локальные горячие клавиши
- единая палитра: цвета кнопок, рамок и подсказок больше не задаются
по месту случайными значениями, а берутся из одного словаря
PALETTE
- повтор по выбранным дням недели: пн/ср/пт, будни, выходные
- предупреждение «за N минут до» — отдельным сигналом, синей строкой в списке
- список сгруппирован по дням, дни недели по-русски
- клик по заголовку дня больше не мешает: кнопки берут первое напоминание ниже
- перенос напоминания с прошлой даты одним кликом
- экспорт и импорт списка
- «отложить до вечера» одной кнопкой
- статистика: сколько выполнено за неделю
- только Windows: автозагрузка через реестр, звук через
winsound. На Linux и macOS интерфейс запустится, но автозагрузка и звук работать не будут - напоминания живут, пока программа запущена. Если выключить компьютер, пропущенные покажутся при следующем старте
- звук в комплекте длится 6.4 секунды — если покажется долгим, замени свой в настройках