對(duì)于鍵盤沒有背光燈的同學(xué)而言,切換大小寫或控制Num鍵開關(guān)的時(shí)候沒有提示,經(jīng)常需要試探性地輸入一些字符來判斷開關(guān)是否打開,體驗(yàn)非常糟糕。
因此,有人就想到自制腳本這一招,一旦觸發(fā)大小寫切換或Num鍵切換就進(jìn)行windows通知提示:
https://github.com/skate1512/Toggle_Keys_Notification
今天我們來試試這個(gè)腳本,此外,我們還可以基于這個(gè)項(xiàng)目,擴(kuò)展成任意一個(gè)按鍵被觸發(fā)或切換都進(jìn)行 windows 通知的腳本:
1.準(zhǔn)備
1.準(zhǔn)備
開始之前,你要確保Python和pip已經(jīng)成功安裝在電腦上,如果沒有,可以訪問這篇文章:超詳細(xì)Python安裝指南 進(jìn)行安裝。
(可選1) 如果你用Python的目的是數(shù)據(jù)分析,可以直接安裝Anaconda:Python數(shù)據(jù)分析與挖掘好幫手—Anaconda,它內(nèi)置了Python和pip.
(可選2) 此外,推薦大家用VSCode編輯器,它有許多的優(yōu)點(diǎn):Python 編程的最好搭檔—VSCode 詳細(xì)指南。
請(qǐng)選擇以下任一種方式輸入命令安裝依賴 :
- Windows 環(huán)境 打開 Cmd (開始-運(yùn)行-CMD)。
- MacOS 環(huán)境 打開 Terminal (command+空格輸入Terminal)。
- 如果你用的是 VSCode編輯器 或 Pycharm,可以直接使用界面下方的Terminal.
pip install win10toast
除此之外,我們需要下載作者的代碼,如果你能聯(lián)通GitHub,請(qǐng)前往以下地址下載:
https://github.com/skate1512/Toggle_Keys_Notification
如果不能聯(lián)通GitHub,或者網(wǎng)絡(luò)速度比較慢,請(qǐng)?jiān)赑ython實(shí)用寶典公眾號(hào)后臺(tái)回復(fù):按鍵觸發(fā)通知 下載本文完整源代碼。
2.源碼使用與解析
2.1 源碼使用
作者的項(xiàng)目可以在 Toggle_Keys_Notification 項(xiàng)目內(nèi),運(yùn)行 notify.py 啟動(dòng)監(jiān)聽:
python notify.py
啟動(dòng)后點(diǎn)擊一下大小寫切換鍵,觸發(fā)通知?jiǎng)t說明代碼正常運(yùn)轉(zhuǎn):
2.2 源碼分析
該項(xiàng)目通過win32gui和win32con實(shí)現(xiàn)了彈出toast進(jìn)行通知的功能,最核心的_show_toast代碼位于 toast.py 中,下面是這個(gè)函數(shù)的部分代碼剖析:
注冊(cè)和創(chuàng)建 window :
message_map = {WM_DESTROY: self.on_destroy, }
# 注冊(cè)Window
self.wc = WNDCLASS()
self.hinst = self.wc.hInstance = GetModuleHandle(None)
self.wc.lpszClassName = str("PythonTaskbar") # 定義該窗口結(jié)構(gòu)的名稱
self.wc.lpfnWndProc = message_map
try:
self.classAtom = RegisterClass(self.wc)
except:
pass
# Window格式
style = WS_OVERLAPPED | WS_SYSMENU
# 創(chuàng)建Window
self.hwnd = CreateWindow(self.classAtom, "Taskbar", style,
0, 0, CW_USEDEFAULT,
CW_USEDEFAULT,
0, 0, self.hinst, None)
UpdateWindow(self.hwnd)
所使用到的win32模塊解析如下。
** GetModuleHandle
** : 獲取一個(gè)應(yīng)用程序或動(dòng)態(tài)鏈接庫的模塊句柄。
** WM_DESTROY
** : 關(guān)閉程序。
** RegisterClass
** : 將定義好的Window屬性保存保存下來。
** WS_OVERLAPPED
** : 重疊式窗口,該式樣窗口 帶有一個(gè)標(biāo)題欄和邊框。
** WS_SYSMENU
** : 具有 SYSTEM 菜單欄的樣式
** CW_USEDEFAULT
** : 采用系統(tǒng)默認(rèn)位置
** CreateWindow
**這個(gè)函數(shù)有非常多的參數(shù),甚至有一個(gè)百度百科來詳細(xì)解析每一個(gè)參數(shù)的具體作用,大家感興趣可以移步:
https://baike.baidu.com/item/CreateWindow/5076220
了解win32這些模塊名稱的意義后,理解上述代碼的邏輯便很輕松了。
圖標(biāo)加載及任務(wù)欄圖標(biāo)顯示配置:
# 圖標(biāo)
if icon_path is not None:
# 獲取圖標(biāo)地址
icon_path = path.realpath(icon_path)
else:
icon_path = resource_filename(Requirement.parse("win10toast"), "win10toast/data/python.ico")
# 加載格式
icon_flags = LR_LOADFROMFILE | LR_DEFAULTSIZE
try:
hicon = LoadImage(self.hinst, icon_path, IMAGE_ICON, 0, 0, icon_flags)
except Exception as e:
logging.error("Some trouble with the icon ({}): {}"
.format(icon_path, e))
hicon = LoadIcon(0, IDI_APPLICATION)
# 任務(wù)欄圖標(biāo)
flags = NIF_ICON | NIF_MESSAGE | NIF_TIP
nid = (self.hwnd, 0, flags, WM_USER + 20, hicon, "Tooltip")
Shell_NotifyIcon(NIM_ADD, nid)
Shell_NotifyIcon(NIM_MODIFY, (self.hwnd, 0, NIF_INFO, WM_USER + 20, hicon, "Balloon Tooltip", msg, 200, title, NIIF_ICON_MASK))
# 等待一會(huì)后銷毀
sleep(duration)
DestroyWindow(self.hwnd)
UnregisterClass(self.wc.lpszClassName, None)
這部分代碼控制了通知彈出框的展示和銷毀。如果你希望通知彈出框久一點(diǎn)再消失,可以適當(dāng)修改傳入的 duration 變量值。
DestroyWindow后,通知彈出框便消失了,整個(gè) show_toast 的過程結(jié)束。
其實(shí)非常簡單,從 CreateWindow 到 DestroyWindow 處理彈出框的各種屬性,然后注銷窗體,完成整個(gè)彈出流程。
3.擴(kuò)展觸發(fā)通知
為了擴(kuò)展監(jiān)聽的按鍵,并能監(jiān)聽按鍵觸發(fā),需要先了解 notify.py 是如何檢測到按鍵變化的。
獲取按鍵狀態(tài):
keyboard = ctypes.WinDLL("User32.dll")
VK_NUMLOCK = 0x90
VK_CAPITAL = 0x14
def get_capslock_state():
"""Returns the current Caps Lock State(On/Off)"""
return "Caps Lock On" if keyboard.GetKeyState(VK_CAPITAL) else "Caps Lock Off"
def get_numlock_state():
"""Returns The current Num Lock State(On/Off)"""
return "Num Lock On" if keyboard.GetKeyState(VK_NUMLOCK) else "Num Lock Off"
可以看到,獲取按鍵狀態(tài)是通過 ** keyboard.GetKeyState(XXXX)
**實(shí)現(xiàn)的。
而這個(gè)XXXX是對(duì)應(yīng)的按鍵的十六進(jìn)制,比如** VK_NUMLOCK
是Num鍵,對(duì)應(yīng)的16進(jìn)制代碼是0x90, VK_CAPITAL
**是大小寫按鍵,對(duì)應(yīng)的十六進(jìn)制代碼是0x14.
變量名是可以用戶自定義的,比如大小寫鍵有些人習(xí)慣稱之為 ** VK_CAPITAL
** ,也有些人喜歡稱之為 ** VK_CAPITAL
** ,都可以,只要其最終對(duì)應(yīng)的變量值為十六進(jìn)制的0x14即可。
部分按鍵16進(jìn)制清單如下(完整版可以閱讀原文查看):
常數(shù)名稱 | 十六進(jìn)制值 | 對(duì)應(yīng)按鍵 |
---|---|---|
VK_BACK | 08 | Backspace鍵 |
VK_TAB | 09 | Tab鍵 |
VK_CLEAR | 0C | Clear鍵(Num Lock關(guān)閉時(shí)的數(shù)字鍵盤5) |
VK_RETURN | 0D | Enter鍵 |
VK_SHIFT | 10 | Shift鍵 |
VK_CONTROL | 11 | Ctrl鍵 |
VK_MENU | 12 | Alt鍵 |
VK_PAUSE | 13 | Pause鍵 |
VK_CAPITAL | 14 | Caps Lock鍵 |
再來看看監(jiān)聽邏輯:
caps_curr = get_capslock_state()
num_curr = get_numlock_state()
while True:
caps_change = get_capslock_state()
num_change = get_numlock_state()
if caps_curr != caps_change:
if caps_change == "Caps Lock On":
pop_up("Caps Lock On", "CapsLock_On.ico")
else:
pop_up("Caps Lock Off", "CapsLock_Off.ico")
caps_curr = caps_change
time.sleep(0.1)
if num_curr != num_change:
if num_change == "Num Lock On":
pop_up("Num Lock On", "NumLock_On.ico")
else:
pop_up("Num Lock Off", "NumLock_Off.ico")
num_curr = num_change
time.sleep(0.2)
在剛開始運(yùn)行監(jiān)聽腳本時(shí),先獲取到按鍵的狀態(tài),在循環(huán)體中,不斷地獲得當(dāng)前按鍵狀態(tài),如果發(fā)生了狀態(tài)變化,則觸發(fā)** pop_up
函數(shù),彈出剛剛我們提到的 show_toast
**函數(shù):
def pop_up(body, icon):
"""Generates Pop-up notification when state changes"""
notification = ToastNotifier()
notification.show_toast("Lock Key State", body, icon_path="assets\"+icon, duration=1.5)
整套監(jiān)聽并通知的機(jī)制還是非常簡單的,如果我們想要自定義一些按鍵,你只需要在開頭添加對(duì)應(yīng)的按鍵的十六進(jìn)制編碼,然后添加一些監(jiān)聽函數(shù)。
比如我們想監(jiān)聽 ESC 按鍵被按下: ** VK_ESCAPE=0x1B
** ,使用 keyboard 模塊添加一個(gè)鉤子函數(shù),監(jiān)聽按鍵:
import keyboard as kb
def hook_esc(button):
"""Alert if ESC button is pressed"""
esc_button = kb.KeyboardEvent('down', VK_ESCAPE, 'ESC')
if button.event_type == 'down' and esc_button.name == button.name:
pop_up("ESC Pressed", "CapsLock_On.ico")
# 敲擊后回填為None
button.event_type = None
然后再在循環(huán)體內(nèi)添加判斷邏輯:
kb.hook(hook_esc)
效果如下:
當(dāng)然,圖標(biāo)和標(biāo)題還可以進(jìn)一步優(yōu)化:
比如將Lock Key State這個(gè)標(biāo)題用 toast_title 變量替代,默認(rèn)為Lock Key State。這樣在調(diào)用pop_up函數(shù)的時(shí)候就能自定義標(biāo)題了,效果如下:
總而言之,能擴(kuò)展的東西非常多,這只是一個(gè)學(xué)習(xí)的例子,如果大家感興趣的話可以在 Python實(shí)用寶典 公眾號(hào)后臺(tái)回復(fù) **按鍵觸發(fā)通知 **下載完整源代碼進(jìn)行改造。
我們的文章到此就結(jié)束啦,如果你喜歡今天的Python 實(shí)戰(zhàn)教程,請(qǐng)持續(xù)關(guān)注Python實(shí)用寶典。
-
開關(guān)
+關(guān)注
關(guān)注
19文章
3275瀏覽量
95049 -
WINDOWS
+關(guān)注
關(guān)注
4文章
3609瀏覽量
91101 -
鍵盤
+關(guān)注
關(guān)注
4文章
865瀏覽量
40525 -
背光燈
+關(guān)注
關(guān)注
1文章
12瀏覽量
7938
發(fā)布評(píng)論請(qǐng)先 登錄
一個(gè)判斷操作系統(tǒng)的VBScript腳本代碼
windows補(bǔ)丁批量安裝腳本
Windows通過組策略設(shè)置開機(jī)自啟動(dòng)腳本
基于腳本的windows與linux之間文件傳輸
使用英特爾Windows和Android平板電腦制作音樂
微軟Windows Core OS消息,通知設(shè)置頁面可實(shí)現(xiàn)上下功能關(guān)聯(lián)
微軟又被吐槽 竟向Windows 10用戶推送全屏通知
Windows 10 NVMe SSD警告通知
使用GSM 900l制作緊急鄰居通知器

【shell腳本分享】性能指標(biāo)監(jiān)控與通知!
如何用bat腳本代替按鍵調(diào)試STM32WL HSE XO的負(fù)載電容

Python簡單制作Windows按鍵通知腳本

Python超簡單制作Windows按鍵通知腳本

Python 制作按鍵觸發(fā)Windows通知的腳本

評(píng)論