Python實現(xiàn)桌面端應(yīng)用消息提醒功能
最近這兩天,在優(yōu)化「TodoList」應(yīng)用的消息提醒功能。PS:TodoList應(yīng)用如果有同學(xué)感興趣,可以查看這篇文章進行安裝:為了不付費,我硬生生用AI開發(fā)了一個跨平臺待辦應(yīng)用
桌面端應(yīng)用消息提醒實現(xiàn)起來真是大有學(xué)問,看著簡單的彈窗消息點擊和消息駐留,開發(fā)起來挺費勁的。

*說明:消息的圖標(biāo)還沒弄好,所以相對看著比較模糊~
前言提要
之前的桌面消息提醒是直接采用 python 調(diào)用指令的方式,讓 powershell 運行腳本來實現(xiàn)彈窗,具體可以看這期的文章:才知道python還可以這樣發(fā)消息提醒的
不過這種方式可定制性太差了,單純使用 powershell 很難實現(xiàn):
- 消息可以駐留在通知中,
- 消息點擊后可以跳轉(zhuǎn)到應(yīng)用
- 支持跨平臺
- 消息含應(yīng)用圖標(biāo)
所以,最終還是要采用第三方組件來實現(xiàn)上述功能。
AI 輔助
我先嘗試 AI 輔助,操作下來,感覺 AI 的差異還是蠻大的。
首先是 AI 智能體實現(xiàn),試了多個應(yīng)用,幾輪對話下來,都達不到預(yù)期。

咨詢 AI 相關(guān)組件,結(jié)果發(fā)現(xiàn) AI 間的回答有偏差,甚至可以說是誤導(dǎo)。
問了四個 AI 應(yīng)用,發(fā)現(xiàn)推薦的第三方依賴包的功能描述都不太準(zhǔn)確。比如:
- 豆包推薦
notify-py,但是這個依賴包做不了點擊跳轉(zhuǎn)功能; Deepseek推薦desktop-notifier最終采用其提供的代碼沒有效果;- 千問說
desktop-notifier消息點擊是完全 “偽回調(diào)”,而其他的AI應(yīng)用諸如Deepseek和gemini是反駁的……

最終根據(jù) Deepseek 和 gemini 的推薦,我采用的是 desktop-notifier。

代碼核心實現(xiàn)
這里我以 gemini 的參考代碼進行介紹。
初始化
這里需要初始化 asyncio 環(huán)境,同時啟動兩個線程,一個維護 asyncio 環(huán)境,一個維護消息隊列。
def __init__(self): self.running = True self.notification_queue = Queue() self.loop = asyncio.new_event_loop() # 1. 先啟動一個純粹運行事件循環(huán)的后臺線程 self.loop_thread = threading.Thread(target=self._run_event_loop, daemon=True) self.loop_thread.start() # 2. 啟動你的隊列監(jiān)聽線程 self.process_thread = threading.Thread(target=self._process_notifications, daemon=True) self.process_thread.start()
asyncio 線程維護
這里 根據(jù) gemini 的建議:通過專門的 loop_thread 維持一個活躍的 loop 是最穩(wěn)健的做法。
def _run_event_loop(self): """專門負責(zé)運行 asyncio 循環(huán)的線程""" asyncio.set_event_loop(self.loop) self.loop.run_forever()
消息處理和發(fā)送
這里是消息發(fā)送,省略了消息回調(diào),在下個章節(jié)會專門介紹。
def _process_notifications(self):
"""處理隊列,將任務(wù)提交給已經(jīng)運行的 loop"""
while self.running:
try:
# 獲取隊列中的數(shù)據(jù)(同步阻塞)
notification = self.notification_queue.get(timeout=1)
# 關(guān)鍵:將協(xié)程任務(wù)提交給正在運行的 self.loop
asyncio.run_coroutine_threadsafe(
self._show_notification(notification),
self.loop
)
except Exception: # 隊列為空超時
continue
async def _show_notification(self, data):
"""真正的異步發(fā)送邏輯"""
# 這里調(diào)用 desktop_notifier.send(...)
print(f"正在發(fā)送通知: {data}")
消息點擊回調(diào)
這個專門起一個章節(jié)是因為這個功能是最影響組件選型的,也是費了我最多時間的。
這是我最終消息發(fā)送的實現(xiàn):
from desktop_notifier.common import Button
# 嘗試使用desktop-notifier顯示通知
await self.notifier.send(
title=title,
message=message,
urgency=Urgency.Critical if priority == 'high' else Urgency.Normal,
on_clicked=lambda: on_click(),
timeout=0 # 0表示通知常駐
)
on_click() 方法的回調(diào)效果是在應(yīng)用隱藏時,喚醒應(yīng)用,因為我使用的是 pywebview 框架,所以用的是 show等函數(shù),具體代碼實現(xiàn)是這樣的:
def on_click():
print("用戶點擊了通知,準(zhǔn)備喚醒窗口...")
# 關(guān)鍵判斷:確保窗口實例存在且未被銷毀
if backend.globals.window:
try:
# 1. 從最小化恢復(fù)
backend.globals.window.restore
# 2. 提到最前顯示(如果之前是 hide 狀態(tài))
backend.globals.window.show
# 3. 某些平臺下可能需要額外聚焦
backend.globals.window.focus
# Windows部分系統(tǒng)需要強制處理下
hwnd = win32gui.FindWindow(None, "TodoList")
if hwnd:
# 恢復(fù)窗口(如果最小化)
win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)
# 強制推至前臺
win32gui.SetForegroundWindow(hwnd)
except Exception as e:
print(f"喚醒失敗,窗口可能已關(guān)閉: {e}")
else:
print("錯誤:找不到窗口實例!")
不過很遺憾,調(diào)試了一下午,最終我實現(xiàn)的僅僅是彈窗消息點擊能觸發(fā)回調(diào),而通知中心的依然觸發(fā)不了。

根據(jù) AI 的分析,是 Python 進程與 Windows 通知系統(tǒng)的 RPC 鏈接(遠程過程調(diào)用) 在某種環(huán)境下斷開了。
嘗試過注冊 AUMID、創(chuàng)建開始菜單快捷方式、使用 URL Protocol 等方式改進,結(jié)果都不奏效……
補充:組件測驗效果
| 組件名稱 | 組件大小 | 組件說明 |
|---|---|---|
desktop_notifier | 30KB | 基本能達到預(yù)期效果,除了通知中心的消息點擊依然觸發(fā)不了回調(diào) |
plyer | 5MB | 體積較大,且 Deepseek 說無法點擊消息跳轉(zhuǎn) |
win10toast-click | 39.5KB | Windows 專用,無法跨平臺,而且版本過老,實測有報錯,需要改源碼 |
notify-py | 0.3 MB | 很輕量化,實測支持消息駐留,但是無法實現(xiàn)點擊跳轉(zhuǎn) |
py-notifier | 0.4 MB | 實測過的給忘了特性啦,千問說不支持消息駐留和點擊跳轉(zhuǎn) |
windows-toasts | 36KB | win10toast-click的 2.0 版本吧,是后面問 gemini 才知道有這個版本的,不過也是通知中心點擊跳轉(zhuǎn)不生效 |
以上就是Python實現(xiàn)桌面端應(yīng)用消息提醒功能的詳細內(nèi)容,更多關(guān)于Python桌面端應(yīng)用消息提醒的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python celery beat實現(xiàn)定時任務(wù)的示例代碼
在日常工作中,我們常常會用到需要周期性執(zhí)行的任務(wù),本文主要介紹了python celery beat實現(xiàn)定時任務(wù)的示例代碼,具有一定的參考價值,感興趣的可以了解一下2024-03-03
淺談Pytorch torch.optim優(yōu)化器個性化的使用
今天小編就為大家分享一篇淺談Pytorch torch.optim優(yōu)化器個性化的使用,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-02-02
Python爬取數(shù)據(jù)并寫入MySQL數(shù)據(jù)庫的實例
今天小編就為大家分享一篇Python爬取數(shù)據(jù)并寫入MySQL數(shù)據(jù)庫的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-06-06
python編程開發(fā)時間序列calendar模塊示例詳解
這篇文章主要為大家介紹了python編程開發(fā)時間序列calendar模塊示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助祝大家多多進步早日升職加薪2021-11-11
Python?如何將?matplotlib?圖表集成進到PDF?中
這篇文章主要介紹了Python?如何將?matplotlib?圖表集成進到PDF?中,文章介紹內(nèi)容詳細,具有一定的參考價值,需要的小伙伴可以參考一下,希望對你的學(xué)習(xí)有所幫助2022-03-03
Tensorflow 如何從checkpoint文件中加載變量名和變量值
這篇文章主要介紹了Tensorflow 如何從checkpoint文件中加載變量名和變量值的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-05-05

