最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python制作Windows按鍵通知腳本

 更新時(shí)間:2022年11月14日 08:38:09   作者:Ckend  
對(duì)于鍵盤沒(méi)有背光燈的同學(xué)而言,切換大小寫或控制Num鍵開關(guān)的時(shí)候沒(méi)有提示,經(jīng)常需要試探性地輸入一些字符來(lái)判斷開關(guān)是否打開,體驗(yàn)非常糟糕。所以本文就來(lái)用Python做一個(gè)Windows按鍵通知腳本,需要的可以參考一下

前言

對(duì)于鍵盤沒(méi)有背光燈的同學(xué)而言,切換大小寫或控制Num鍵開關(guān)的時(shí)候沒(méi)有提示,經(jīng)常需要試探性地輸入一些字符來(lái)判斷開關(guān)是否打開,體驗(yàn)非常糟糕。

因此,有人就想到自制腳本這一招,一旦觸發(fā)大小寫切換或Num鍵切換就進(jìn)行windows通知提示:

圖片

https://github.com/skate1512/Toggle_Keys_Notification

今天我們來(lái)試試這個(gè)腳本,此外,我們還可以基于這個(gè)項(xiàng)目,擴(kuò)展成任意一個(gè)按鍵被觸發(fā)或切換都進(jìn)行 windows 通知的腳本:

1.準(zhǔn)備

開始之前,你要確保Python和pip已經(jīng)成功安裝在電腦上,如果沒(méi)有,可以訪問(wèn)這篇文章:超詳細(xì)Python安裝指南進(jìn)行安裝。

(可選1)如果你用Python的目的是數(shù)據(jù)分析,可以直接安裝Anaconda,它內(nèi)置了Python和pip.

(可選2)此外,推薦大家用VSCode編輯器,它有許多的優(yōu)點(diǎn)

請(qǐng)選擇以下任一種方式輸入命令安裝依賴

1. Windows 環(huán)境 打開 Cmd (開始-運(yùn)行-CMD)。

2. MacOS 環(huán)境 打開 Terminal (command+空格輸入Terminal)。

3. 如果你用的是 VSCode編輯器 或 Pycharm,可以直接使用界面下方的Terminal.

pip?install?win10toast

除此之外,我們需要下載作者的代碼,如果你能聯(lián)通GitHub,請(qǐng)前往以下地址下載:

https://github.com/skate1512/Toggle_Keys_Notification

2.源碼使用與解析

2.1 源碼使用

作者的項(xiàng)目可以在 Toggle_Keys_Notification 項(xiàng)目?jī)?nèi),運(yùn)行 notify.py 啟動(dòng)監(jiān)聽:

python?notify.py

啟動(dòng)后點(diǎn)擊一下大小寫切換鍵,觸發(fā)通知?jiǎng)t說(shuō)明代碼正常運(yùn)轉(zhuǎn):

2.2 源碼分析

該項(xiàng)目通過(guò)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)鏈接庫(kù)的模塊句柄。

WM_DESTROY: 關(guān)閉程序。

RegisterClass:將定義好的Window屬性保存保存下來(lái)。

WS_OVERLAPPED: 重疊式窗口,該式樣窗口 帶有一個(gè)標(biāo)題欄和邊框。

WS_SYSMENU: 具有 SYSTEM 菜單欄的樣式

CW_USEDEFAULT: 采用系統(tǒng)默認(rèn)位置

CreateWindow這個(gè)函數(shù)有非常多的參數(shù),甚至有一個(gè)百度百科來(lái)詳細(xì)解析每一個(gè)參數(shù)的具體作用

了解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 的過(guò)程結(jié)束。

其實(shí)非常簡(jiǎn)單,從 CreateWindow 到 DestroyWindow 處理彈出框的各種屬性,然后注銷窗體,完成整個(gè)彈出流程。

3.擴(kuò)展觸發(fā)通知

為了擴(kuò)展監(jiān)聽的按鍵,并能監(jiān)聽按鍵觸發(fā),需要先了解 notify.py 是如何檢測(cè)到按鍵變化的。

獲取按鍵狀態(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)是通過(guò)  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_BACK08Backspace鍵
VK_TAB09Tab鍵
VK_CLEAR0CClear鍵(Num Lock關(guān)閉時(shí)的數(shù)字鍵盤5)
VK_RETURN0DEnter鍵
VK_SHIFT10Shift鍵
VK_CONTROL11Ctrl鍵
VK_MENU12Alt鍵
VK_PAUSE13Pause鍵
VK_CAPITAL14Caps Lock鍵

再來(lái)看看監(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ī)制還是非常簡(jiǎn)單的,如果我們想要自定義一些按鍵,你只需要在開頭添加對(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)為L(zhǎng)ock Key State。這樣在調(diào)用pop_up函數(shù)的時(shí)候就能自定義標(biāo)題了,效果如下:

到此這篇關(guān)于Python制作Windows按鍵通知腳本的文章就介紹到這了,更多相關(guān)Python Windows按鍵通知內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python讀取測(cè)試數(shù)據(jù)的多種方式

    python讀取測(cè)試數(shù)據(jù)的多種方式

    本文主要介紹了python讀取測(cè)試數(shù)據(jù)的多種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • Python函數(shù)的周期性執(zhí)行實(shí)現(xiàn)方法

    Python函數(shù)的周期性執(zhí)行實(shí)現(xiàn)方法

    這篇文章主要介紹了Python函數(shù)的周期性執(zhí)行實(shí)現(xiàn)方法,涉及Python使用sched模塊實(shí)現(xiàn)函數(shù)周期性調(diào)度觸發(fā)的相關(guān)技巧,需要的朋友可以參考下
    2016-08-08
  • Python爬取微信小程序通用方法代碼實(shí)例詳解

    Python爬取微信小程序通用方法代碼實(shí)例詳解

    這篇文章主要介紹了Python爬取微信小程序通用方法代碼實(shí)例詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Python操作redis實(shí)例小結(jié)【String、Hash、List、Set等】

    Python操作redis實(shí)例小結(jié)【String、Hash、List、Set等】

    這篇文章主要介紹了Python操作redis的常見方法,結(jié)合實(shí)例形式總結(jié)分析了Python redis操作中String、Hash、List、Set等相關(guān)操作函數(shù)與使用技巧,需要的朋友可以參考下
    2019-05-05
  • Python操作Mysql實(shí)例代碼教程在線版(查詢手冊(cè))

    Python操作Mysql實(shí)例代碼教程在線版(查詢手冊(cè))

    本文介紹了Python操作MYSQL、執(zhí)行SQL語(yǔ)句、獲取結(jié)果集、遍歷結(jié)果集、取得某個(gè)字段、獲取表字段名、將圖片插入數(shù)據(jù)庫(kù)、執(zhí)行事務(wù)等各種代碼實(shí)例和詳細(xì)介紹,代碼居多,是一桌豐盛唯美的代碼大餐
    2013-02-02
  • Python?sklearn?中的?make_blobs()?函數(shù)示例詳解

    Python?sklearn?中的?make_blobs()?函數(shù)示例詳解

    make_blobs()?是?sklearn.datasets中的一個(gè)函數(shù),這篇文章主要介紹了Python?sklearn?中的?make_blobs()?函數(shù),本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • Python中列表的常用操作詳解

    Python中列表的常用操作詳解

    這篇文章主要為大家詳細(xì)介紹了python字典的常用操作方法,主要內(nèi)容包含Python中列表(List)的詳解操作方法,包含創(chuàng)建、訪問(wèn)、更新、刪除、其它操作等,需要的朋友可以參考下
    2021-09-09
  • pandas將DataFrame的列變成行索引的方法

    pandas將DataFrame的列變成行索引的方法

    下面小編就為大家分享一篇pandas將DataFrame的列變成行索引的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-04-04
  • python如何求兩數(shù)之和及多數(shù)之和

    python如何求兩數(shù)之和及多數(shù)之和

    這篇文章主要介紹了python如何求兩數(shù)之和及多數(shù)之和問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • Pycharm配置導(dǎo)入torch報(bào)錯(cuò)Traceback的問(wèn)題及解決

    Pycharm配置導(dǎo)入torch報(bào)錯(cuò)Traceback的問(wèn)題及解決

    這篇文章主要介紹了Pycharm配置導(dǎo)入torch報(bào)錯(cuò)Traceback的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12

最新評(píng)論

闽清县| 通州区| 呼伦贝尔市| 江油市| 桓仁| 三江| 普安县| 九龙县| 界首市| 名山县| 和林格尔县| 大兴区| 扶沟县| 沙湾县| 福州市| 和林格尔县| 杂多县| 莱芜市| 南召县| 绵阳市| 六盘水市| 龙游县| 蒲江县| 大港区| 曲阳县| 米林县| 噶尔县| 饶河县| 读书| 通渭县| 泽普县| 封开县| 吉木乃县| 石渠县| 开原市| 黑龙江省| 伊春市| 颍上县| 宜阳县| 昂仁县| 榆中县|