0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

制作Windows按键通知脚本

汽车电子技术 来源:Python实用宝典 作者:Ckend 2023-02-24 10:39 次阅读

图片

对于键盘没有背光灯的同学而言,切换大小写或控制Num键开关的时候没有提示,经常需要试探性地输入一些字符来判断开关是否打开,体验非常糟糕。

因此,有人就想到自制脚本这一招,一旦触发大小写切换或Num键切换就进行windows通知提示:

https://github.com/skate1512/Toggle_Keys_Notification

今天我们来试试这个脚本,此外,我们还可以基于这个项目,扩展成任意一个按键被触发或切换都进行 windows 通知的脚本:

图片

1.准备

1.准备

开始之前,你要确保Pythonpip已经成功安装在电脑上,如果没有,可以访问这篇文章:超详细Python安装指南 进行安装。

(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.

(可选2) 此外,推荐大家用VSCode编辑器,它有许多的优点:Python 编程的最好搭档—VSCode 详细指南。

请选择以下任一种方式输入命令安装依赖

  1. Windows 环境 打开 Cmd (开始-运行-CMD)。
  2. MacOS 环境 打开 Terminal (command+空格输入Terminal)。
  3. 如果你用的是 VSCode编辑器 或 Pycharm,可以直接使用界面下方的Terminal.
pip install win10toast

除此之外,我们需要下载作者的代码,如果你能联通GitHub,请前往以下地址下载:

https://github.com/skate1512/Toggle_Keys_Notification

如果不能联通GitHub,或者网络速度比较慢,请在Python实用宝典公众号后台回复:按键触发通知 下载本文完整源代码。

2.源码使用与解析

2.1 源码使用

作者的项目可以在 Toggle_Keys_Notification 项目内,运行 notify.py 启动监听:

python notify.py

启动后点击一下大小写切换键,触发通知则说明代码正常运转:

图片

2.2 源码分析

该项目通过win32gui和win32con实现了弹出toast进行通知的功能,最核心的_show_toast代码位于 toast.py 中,下面是这个函数的部分代码剖析:

注册和创建 window :

message_map = {WM_DESTROY: self.on_destroy, }
# 注册Window
self.wc = WNDCLASS()
self.hinst = self.wc.hInstance = GetModuleHandle(None)
self.wc.lpszClassName = str("PythonTaskbar") # 定义该窗口结构的名称
self.wc.lpfnWndProc = message_map
try:
    self.classAtom = RegisterClass(self.wc)
except:
    pass
# Window格式
style = WS_OVERLAPPED | WS_SYSMENU
# 创建Window
self.hwnd = CreateWindow(self.classAtom, "Taskbar", style,
                         0, 0, CW_USEDEFAULT,
                         CW_USEDEFAULT,
                         0, 0, self.hinst, None)
UpdateWindow(self.hwnd)

所使用到的win32模块解析如下。

** GetModuleHandle ** : 获取一个应用程序或动态链接库的模块句柄。

** WM_DESTROY ** : 关闭程序。

** RegisterClass ** : 将定义好的Window属性保存保存下来。

** WS_OVERLAPPED ** : 重叠式窗口,该式样窗口 带有一个标题栏和边框。

** WS_SYSMENU ** : 具有 SYSTEM 菜单栏的样式

** CW_USEDEFAULT ** : 采用系统默认位置

** CreateWindow **这个函数有非常多的参数,甚至有一个百度百科来详细解析每一个参数的具体作用,大家感兴趣可以移步:

https://baike.baidu.com/item/CreateWindow/5076220

了解win32这些模块名称的意义后,理解上述代码的逻辑便很轻松了。

图标加载及任务栏图标显示配置:

# 图标
if icon_path is not None:
    # 获取图标地址
    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)
# 任务栏图标
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))

# 等待一会后销毁
sleep(duration)
DestroyWindow(self.hwnd)
UnregisterClass(self.wc.lpszClassName, None)

这部分代码控制了通知弹出框的展示和销毁。如果你希望通知弹出框久一点再消失,可以适当修改传入的 duration 变量值。

DestroyWindow后,通知弹出框便消失了,整个 show_toast 的过程结束。

其实非常简单,从 CreateWindow 到 DestroyWindow 处理弹出框的各种属性,然后注销窗体,完成整个弹出流程。

3.扩展触发通知

为了扩展监听的按键,并能监听按键触发,需要先了解 notify.py 是如何检测到按键变化的。

获取按键状态:

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"

可以看到,获取按键状态是通过 ** keyboard.GetKeyState(XXXX) **实现的。

而这个XXXX是对应的按键的十六进制,比如** VK_NUMLOCK 是Num键,对应的16进制代码是0x90, VK_CAPITAL **是大小写按键,对应的十六进制代码是0x14.

变量名是可以用户自定义的,比如大小写键有些人习惯称之为 ** VK_CAPITAL ** ,也有些人喜欢称之为 ** VK_CAPITAL ** ,都可以,只要其最终对应的变量值为十六进制的0x14即可。

部分按键16进制清单如下(完整版可以阅读原文查看):

常数名称 十六进制值 对应按键
VK_BACK 08 Backspace键
VK_TAB 09 Tab键
VK_CLEAR 0C Clear键(Num Lock关闭时的数字键盘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键

再来看看监听逻辑:

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)

在刚开始运行监听脚本时,先获取到按键的状态,在循环体中,不断地获得当前按键状态,如果发生了状态变化,则触发** pop_up 函数,弹出刚刚我们提到的 show_toast **函数:

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)

整套监听并通知的机制还是非常简单的,如果我们想要自定义一些按键,你只需要在开头添加对应的按键的十六进制编码,然后添加一些监听函数。

比如我们想监听 ESC 按键被按下: ** VK_ESCAPE=0x1B ** ,使用 keyboard 模块添加一个钩子函数,监听按键:

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

然后再在循环体内添加判断逻辑:

kb.hook(hook_esc)

效果如下:

图片

当然,图标和标题还可以进一步优化:

比如将Lock Key State这个标题用 toast_title 变量替代,默认为Lock Key State。这样在调用pop_up函数的时候就能自定义标题了,效果如下:

图片

总而言之,能扩展的东西非常多,这只是一个学习的例子,如果大家感兴趣的话可以在 Python实用宝典 公众号后台回复 **按键触发通知 **下载完整源代码进行改造。

我们的文章到此就结束啦,如果你喜欢今天的Python 实战教程,请持续关注Python实用宝典。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 开关
    +关注

    关注

    19

    文章

    2996

    浏览量

    92712
  • WINDOWS
    +关注

    关注

    3

    文章

    3440

    浏览量

    87144
  • 键盘
    +关注

    关注

    4

    文章

    843

    浏览量

    39004
  • 背光灯
    +关注

    关注

    1

    文章

    12

    浏览量

    7738
收藏 人收藏

    评论

    相关推荐

    一个判断操作系统的VBScript脚本代码

    西门子触摸屏基于不同的Windows操作系统,有的是标准的Windows系统,有的是嵌入式操作系统Windows CE。这两种系统对于VBScript脚本的支持不同,因此在使用
    发表于 09-21 14:56 474次阅读

    windows补丁批量安装脚本

    windows补丁批量安装脚本现在Windows的补丁已经是越来越多了,累积下来有几十个,就算发布一次也有近十个,一个一个点击安装真累……而且直接点击安装的话,还会在 Windows
    发表于 05-07 08:55

    Windows通过组策略设置开机自启动脚本

    Configuration -> Windows Settings -> Scripts (Startup/Shutdown) -> Startup在弹出窗口中选择上面的脚本文件,然后确定。也
    发表于 07-05 08:06

    基于脚本windows与linux之间文件传输

    1.在Windows系统上的某个文件需要传送到Linux系统的设备上;2.因为自动化的要求不能人工操作,需要编写脚本,然后在程序中调用cmd命令执行这个脚本
    发表于 07-24 06:06

    C#结合SMTP实现邮件报警通知分享

    写在前面C#是微软推出的一门面向对象的通用型编程语言,它除了可以开发PC软件、网站(借助http://ASP.NET)和APP(基于 Windows Phone),还能作为游戏脚本,编写游戏逻辑
    发表于 07-02 06:57

    按键精灵(Quick Macro)简体中文绿色特别版

    按键精灵是一个模拟鼠标键盘动作的软件。通过制作脚本
    发表于 06-10 09:13 0次下载

    微软Windows Core OS消息,通知设置页面可实现上下功能关联

      根据LinkedIn文件显示:“在桌面的通知设置页面和Windows设置的通知设置页面上实现上下功能关联”。由此来看微软或计划在系统“通知设置”页面上实现功能“上下关联”以简化
    的头像 发表于 02-04 15:22 2961次阅读

    微软又被吐槽 竟向Windows 10用户推送全屏通知

    为了推荐自家的业务,微软向所有的Windows 10用户推送了全屏通知
    的头像 发表于 03-17 09:11 1279次阅读

    什么是脚本脚本程序学习

    脚本中编写VB脚本代码。可以象使用系统函数一样使用项目中完成的脚本。创建脚本时,确定其型号并定义传送参数。“Function”类型的脚本
    的头像 发表于 05-11 10:39 6083次阅读
    什么是<b class='flag-5'>脚本</b>?<b class='flag-5'>脚本</b>程序学习

    Windows 10 NVMe SSD警告通知

    Windows 10 Insider Preview Build 20226的公告中,微软高级项目经理Brandon LeBlanc说,这项新的驱动器运行状况监视功能“旨在检测NVMe SSD
    的头像 发表于 12-18 09:52 2248次阅读

    使用GSM 900l制作紧急邻居通知

    电子发烧友网站提供《使用GSM 900l制作紧急邻居通知器.zip》资料免费下载
    发表于 11-21 11:42 0次下载
    使用GSM 900l<b class='flag-5'>制作</b>紧急邻居<b class='flag-5'>通知</b>器

    【shell脚本分享】性能指标监控与通知

    今天浩道跟大家分享一个关于性能监控与通知相关的shell脚本
    的头像 发表于 01-09 09:35 842次阅读

    Python简单制作Windows按键通知脚本

    ,扩展成任意一个按键被触发或切换都进行 windows 通知脚本: 1.准备 开始之前,你要确保Python和pip已经成功安装
    的头像 发表于 10-17 11:10 294次阅读
    Python简单<b class='flag-5'>制作</b><b class='flag-5'>Windows</b><b class='flag-5'>按键</b><b class='flag-5'>通知</b><b class='flag-5'>脚本</b>

    Python超简单制作Windows按键通知脚本

    ,扩展成任意一个按键被触发或切换都进行 windows 通知脚本: 1.准备 1.准备 开始之前,你要确保Python和pip已经成
    的头像 发表于 11-01 09:24 246次阅读
    Python超简单<b class='flag-5'>制作</b><b class='flag-5'>Windows</b><b class='flag-5'>按键</b><b class='flag-5'>通知</b><b class='flag-5'>脚本</b>

    Python 制作按键触发Windows通知脚本

    ,扩展成任意一个按键被触发或切换都进行 windows 通知脚本: 1.准备 开始之前,你要确保Python和pip已经成功安装
    的头像 发表于 11-01 16:09 297次阅读
    Python <b class='flag-5'>制作</b><b class='flag-5'>按键</b>触发<b class='flag-5'>Windows</b><b class='flag-5'>通知</b>的<b class='flag-5'>脚本</b>