Python如何按下指定按键后执行特定的操作

2021/12/10更新

看到朋友们都很在关注这个内容,我花了一上午改进了一下代码,更加优雅一些,也更建议这样使用,当然是自己琢磨的啦!!!

import threading
from pynput.keyboard import Listener

按键列表 = {"'1'": '1', "'2'": '2', "'3'": '3', "'4'": '4', "'5'": '5', "'6'": '6', "'7'": '7', "'8'": '8', "'9'": '9',
        "'0'": '0', "'a'": 'a', "'b'": 'b', "'c'": 'c', "'d'": 'd', "'e'": 'e', "'f'": 'f', "'g'": 'g', "'h'": 'h',
        "'i'": 'i', "'j'": 'j', "'k'": 'k', "'l'": 'l', "'m'": 'm',
        "'n'": 'n', "'o'": 'o', "'p'": 'p', "'q'": 'q', "'r'": 'r', "'s'": 's', "'t'": 't', "'u'": 'u', "'v'": 'v',
        "'w'": 'w', "'x'": 'x',
        "'y'": 'y', "'z'": 'z', "'A'": 'a', "'B'": 'b',
        "'C'": 'c', "'D'": 'd', "'E'": 'e', "'F'": 'f', "'G'": 'g', "'H'": 'h', "'I'": 'i', "'J'": 'j', "'K'": 'k',
        "'L'": 'l', "'M'": 'm',
        "'N'": 'n', "'O'": 'o', "'P'": 'p', "'Q'": 'q', "'R'": 'r', "'S'": 's', "'T'": 't', "'U'": 'u', "'V'": 'v',
        "'W'": 'w', "'X'": 'x',
        "'Y'": 'y', "'Z'": 'z', "Key.f1": "f1", "Key.f2": "f2", "Key.f3": "f3", "Key.f4": "f4", "Key.f5": "f5",
        "Key.f6": "f6",
        "Key.f7": "f7", "Key.f8": "f8", "Key.f9": "f9", "Key.f10": "f10", "Key.f11": "f11", "Key.f12": "f12",
        "Key.esc": "esc",
        "'`'": "`",
        "Key.tab": "tab", "Key.caps_lock": "caps_lock", "Key.shift": "shift", "Key.shift_r": "shift",
        "Key.ctrl_l": "ctrl", "<255>": "fn",
        "Key.cmd": "win",
        "Key.alt_l": "alt", "Key.space": "space", "Key.alt_r": "alt", "Key.menu": "menu", "Key.ctrl_r": "ctrl",
        "','": ",",
        "'.'": ".", "'/'": "/", "';'": ';', "\"'\"": "'", "'['": "[", "']'": "]", "Key.enter": "enter", "'\\'": "\\",
        "'\\\\'": "、", "<12>": "5", "'*'": "*",
        "'-'": "-",
        "'='": "=", "'+'": "+", "Key.backspace": "backspace", "Key.print_screen": "print_screen",
        "Key.insert": "insert",
        "Key.delete": "delete", "Key.left": "left", "Key.down": "down", "Key.right": "right", "Key.up": "up",
        "Key.home": "home",
        "Key.end": "end", "Key.page_up": "page_up", "Key.page_down": "page_down", "Key.num_lock": "lock"}
快捷键最大长度 = 5


# 固定长度为某一固定值的数组, 存储按下的按键
class speedList:
    def __init__(self):
        self.maxlen = 快捷键最大长度
        self.list = []

    def push(self, e):
        # 根据按键列表获取实际的按键名字
        try:
            self.list.append(按键列表[str(e)])
        except:
            print("没有这个按键: ", e)
        if (len(self.list) > self.maxlen):
            self.list.pop(0)

    def get(self):
        return self.list


监听的数组 = speedList()

# key: 快捷键字符串  value函数
函数map = {}


def 监听按键后的处理(key):
    global 监听的数组
    监听的数组.push(key)
    for i in 获取所有组合():
        try:
            函数_list = 函数map[i]
            for now_函数 in 函数_list:
                now_函数()
        except:
            pass


def 获取所有组合():
    # 如  a b c d 的组合有 d cd bcd abcd
    res = []
    数组 = 监听的数组.get()
    index = len(数组) - 1
    while index >= 0:
        s = ""
        for i in range(index, len(数组)):
            s += 数组[i]
        res.append(s)
        index -= 1
    return res


def 监听按键():
    with Listener(on_press=监听按键后的处理) as listener:
        listener.join()


def 判断是否在数组里(定义的快捷键):
    # 只取前n个(n为快捷键的长度) , 防止重复执行如 快捷键为f  ccccf  会执行5次, 因为f一直在里面
    return 监听的数组.get().copy()[-len(定义的快捷键)::] == 定义的快捷键


def 快捷键(*kwds):
    # 因为装饰器只会执行一次,所以这里是将函数列表添加进去,而不是进行判断操作
    global 函数map

    def decorate(f):
        global 函数map
        if len(kwds) <= 快捷键最大长度:
            try:
                函数列表 = 函数map[元组转为字符串(kwds)]
                函数列表.append(f)
                函数map[元组转为字符串(kwds)] = 函数列表
            except:
                函数map[元组转为字符串(kwds)] = [f]
        else:
            print("快捷键最大长度为: ", 快捷键最大长度, " 快捷键", kwds, " 不符合要求")
        return f

    return decorate


def 元组转为字符串(kwds):
    res = ""
    for i in kwds:
        res = res + i.lower()
    return res


threading.Thread(target=监听按键).start()

使用

from 监控按键 import 快捷键


@快捷键("c")
def 第三个函数():
    print("我按下了c")


@快捷键("ctrl", "v")
def 第三个函数():
    print("粘贴")


@快捷键("a", "b", "c", "d", "e")
def 第三个函数():
    print("dadadadad")

----------------------------以下是原内容 ----------------------------

库:pynput
安装:pip install pynput
话不多说直接上代码:

from pynput.keyboard import Listener
import time


def on_press(key):
    pass


def on_release(key):
    all_key.append(str(key))
    print(all_key)
    if "'r'" in all_key:
        print("开大招了")
        all_key.clear()

    if "'q'" in all_key:
        print("开q技能了")
        all_key.clear()

    if "'w'" in all_key:
        print("开w技能了")
        all_key.clear()
    if "'e'" in all_key:
        print("开e技能了")
        all_key.clear()

    if 'Key.ctrl_l' in all_key and "'c'" in all_key:  # ctrl+c
        print('这是复制键')
        all_key.clear()

    if 'Key.ctrl_l' in all_key and "'v'" in all_key:  # ctrl+v
        print('这是粘贴键')
        all_key.clear()

    try:
        if all_key[-1] == 'Key.ctrl_l':
            time1 = time.time()
            while True:
                if time.time() - time1 >= 1:
                    all_key.clear()
                    break
    except:
        pass

    # if key == Key.esc:  # 停止监听
    #     return Falseurn False


def start_listen():
    with Listener(on_press=None, on_release=on_release) as listener:
        listener.join()


if __name__ == '__main__':
    all_key = []
    start_listen()

基本思路

每当按下一个按键后,会将按下的按键名称添加进特定的列表all_key中,从而根据列表里面的元素进行判断,若符合则证明“按下了特定的按键”,从而执行想要执行的函数。

缺点

程序中有一个all_key.clear()函数,是清除列表的所有元素,那么什么时候清除是一个问题。比如我按下了Ctrl键,那么’Key.ctrl_l’元素就会添加进去,但是我过了一会儿再按下c键,这时程序就会根据列表中有’Key.ctrl_l’和’c’从而认为我们按下了复制快捷键,可是我们并没有按下Ctrl+c。

我在想根据元素添加的时间来判断,比如检测到列表中有’Key.ctrl_l’元素,过0.5秒后再进行检测看有没有‘c’元素,如果有则证明按下了复制快捷键,如果没有检测到‘c’那么就执行all_key.clear()函数。
总之什么时候执行all_key.clear()函数是需要解决的问题

  • 17
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

原来你是小幸运

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值