pynput 鼠标键盘监听如何退出。

一,安装pynput库

使用Python对键盘鼠标进行监听我们一般使用 pynput 库中的 pynput.keyboard 和 pynput.mouse

所以我们首先需要安装pynput 库

pip install pynput

         

二,鼠标键盘控制

1,鼠标控制:

        实例化鼠标对象:

from pynput import mouse

contro = mouse.Controller()

        控制鼠标的方法:

from pynput import mouse


# 实列化对象                                       
control2 = mouse.Controller()

#鼠标移动,相当于X坐标加10,Y坐标加10
control2.move(10, 10)

#鼠标直接到 (100, 100)的位置
control2.position(100, 100)

#鼠标点击  .click(Button, count)
    #左键 mouse.Button.left
    #右键 mouse.Button.right
    #中键 mouse.Button.middle
    #count 点击的次数
control2.click(mouse.Button.left, 1)


#按住鼠标按键
control2.press(mouse.Button.left)

#松开鼠标按键
control2.release(mouse.Button.left)

#控制鼠标滑轮 control2.scroll(dx, int) dx 为滑动的距离, 第二个参数是上下
control2.scroll(10, -1)
        2,键盘控制:

       键盘和鼠标控制是大同小异的,也就一下参数的变化。

        实例化键盘对象:

# 导入pynput库
from pynput import keyboard

# 实列化键盘控制对象
control1 = keyboard.Controller()

        键盘控制的方法:

# 导入pynput库
from pynput import keyboard

# 实列化键盘控制对象
control1 = keyboard.Controller()

# 控制键盘按下 a 键
control1.press('a')


# 控制键盘松开 a 键
control1.release('a')


# 控制键盘执行一次按下和松开
control1.pressed('a')

三, 键盘鼠标的监听

        1,键盘监听

        监听键盘呢只监听两个事件,一个是按键按下,一个是按键松开。

# 导入pynput库
from pynput import keyboard



# 定义两个函数,当监听到按键按下或按键松开时执行

def key_press(event):
    print(f"{event.key} 被按下了!!")

def key_release(event):
    print(f"{event.key} 被松开了!!")


#  重点---------非阻塞型监听                 这里是调用函数对象,不能带有括号

my_listener = keyboard.Listener(on_press=key_press, on_release=key_release)

# 这种监听就像是你喊开始就开始,你喊结束他就结束

# 监听开始
print("监听开始了")
my_listener.start()

# 监听结束
my_listener.stop()
print("监听结束了")

# 按ESC退出阻塞型监听
def on_down(event):
    if event == keyboard.Key.esc:
        sys.exit()

#   阻塞型监听    相当于一个While 循环,一直在监听,这个监听没退出不会执行后面的代码
with keyboard.Listener(on_press= on_down) as listener:
        listener.join()

print("监听结束了")
2,鼠标监听

鼠标的话有三个事件进行监听,分别是移动,按键,滑轮。

from pynput import mouse


# 定义三个函数对应鼠标的三个监听事件

def on_move(self, x, y):
    print(f"鼠标移动到了 {x},{y} 的位置")

def on_m_scroll(self, x, y, dx, dy):
    print("滑动了滑轮.")

def on_m_click(self, x, y, button, pressed):
    if button == mouse.Button.left:
        print("鼠标左键按下")
    
    elif button == mouse.Button.right:
        printt("鼠标右键按下")
    
#   非阻塞型监听

my_listener = mouse.Listener(on_move=on_move, on_scroll=on_m_scroll, on_click=on_m_click)

#  监听开始
print("监听开始了....")
my_listener.start()

# 监听结束
print("监听结束了")
my_listener.stop()

#   阻塞型监听
with mouse.Listener(on_move=on_move, on_scroll=on_m_scroll, on_click=on_m_click) as listener:
        listener.join()

四,自己写的键盘鼠标监听记录,并实现执行记录的操作。

       其中找监听结束的方法消耗我不少时间,因为我一开始一直使用的是阻塞型监听方法,所以开始记录后无法结束记录,尝试过多线程和多进程结束方法都不行,原因是监听对象本身就是一个线程。

import sys
import tkinter
from tkinter import filedialog
from tkinter import messagebox
from pynput import keyboard
from pynput import mouse
import threading
import time
import inspect
import ctypes

win = tkinter.Tk()
win.title("宏录制")
win.geometry("260x100")

special_key = {
    "Key.backspace": keyboard.Key.backspace,
    "Key.enter": keyboard.Key.enter,
    "Key.space": keyboard.Key.space,
    "Key.shift_r": keyboard.Key.shift_r,
    "Key.ctrl_r": keyboard.Key.ctrl_r,
    "Key.alt_l": keyboard.Key.alt_l,
    "Key.ctrl_l": keyboard.Key.ctrl_l,
    "Key.shift": keyboard.Key.shift,
    "Key.caps_lock": keyboard.Key.caps_lock,
    "Key.tab": keyboard.Key.tab,
    "Key.page_down": keyboard.Key.page_down,
    "Key.page_up": keyboard.Key.page_up,
    "Key.end": keyboard.Key.end,
    "Key.home": keyboard.Key.home
}
mouse_key = {
    "Button.left": mouse.Button.left,
    "Button.right": mouse.Button.right
}


def select_file():
    txt_path = filedialog.askopenfilename(
        title='请选择文件',
        # 筛选常见图片文件
        filetypes=[('文本', '.txt .TXT')],
    )

    if txt_path and txt_path.endswith(('.txt', '.TXT')):
        file_path_entry["state"] = "normal"
        # 图像路径
        file_path_entry.delete(0, "end")
        file_path_entry.insert(0, txt_path)


# def _async_raise(tid, exctype):
#     """raises the exception, performs cleanup if needed"""
#     tid = ctypes.c_long(tid)
#     if not inspect.isclass(exctype):
#         exctype = type(exctype)
#     res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
#
#     if res == 0:
#         raise ValueError("invalid thread id")
#     elif res != 1:
#         # """if it returns a number greater than one, you're in trouble,
#         # and you should call it again with exc=NULL to revert the effect"""
#         ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
#         raise SystemError("PyThreadState_SetAsyncExc failed")
#
#
# def stop_thread(thread):
#     _async_raise(thread.ident, SystemExit)
#

def do_it():
    file_path = file_path_entry.get()
    last_time = 0
    if file_path:
        with open(file_path, "r") as f:
            do_list = f.read().split("\n")
        if do_list[0] != "hello world!!":
            messagebox.showinfo("文件选择错误!!", "文件选择错误!!")
        else:
            control1 = keyboard.Controller()
            control2 = mouse.Controller()
            print(len(do_list))
            s = 0
            for i in do_list[1:-1]:
                do = i.split(" ")

                s += 1
                last_time = float(do[0]) - last_time
                if last_time < 0.001:
                    pass
                else:
                    time.sleep(last_time)
                    if do[1] == "on_down":
                        if "Key" in do[2]:
                            control1.press(special_key[do[2]])

                        else:
                            control1.press(do[2].replace("'", ""))

                    elif do[1] == "on_up":
                        if "Key" in do[2]:
                            control1.release(special_key[do[2]])

                        else:
                            control1.release(do[2].replace("'", ""))

                    elif do[1] == "on_move":
                        coordinate = do[2].split(",")
                        control2.position = (int(coordinate[0]), int(coordinate[1]))

                    elif do[1] == "on_m_scroll":
                        control2.scroll(0, int(do[2]))
                    elif do[1] == "on_m_click":
                        if do[3] == "True":
                            control2.press(mouse_key[do[2]])
                        else:
                            control2.release(mouse_key[do[2]])

                last_time = float(do[0])
    messagebox.showinfo("提示", "执行完成!!")


class my_do:
    def __init__(self):
        self.start = 0
        self.file_name = 0
        self.m_l = 0
        self.k_l = 0

    def on_down(self, event):
        s = (time.time() - self.start)
        with open(f"{self.file_name}.txt", 'a') as f:
            f.write(f"{s} on_down {event}\n")

    def on_up(self, event):
        s = (time.time() - self.start)
        with open(f"{self.file_name}.txt", 'a') as f:
            f.write(f"{s} on_up {event}\n")

    def on_move(self, x, y):
        print(1)
        s = (time.time() - self.start)
        with open(f"{self.file_name}.txt", 'a') as f:
            f.write(f"{s} on_move {x},{y}\n")

    def on_m_scroll(self, x, y, dx, dy):
        s = (time.time() - self.start)
        with open(f"{self.file_name}.txt", 'a') as f:
            f.write(f"{s} on_m_scroll {dy}\n")

    def on_m_click(self, x, y, button, pressed):
        s = (time.time() - self.start)
        with open(f"{self.file_name}.txt", 'a') as f:
            f.write(f"{s} on_m_click {button} {pressed}\n")


dodo = my_do()


def make_do():
    dodo.file_name = time.strftime("%Y.%m.%d %H.%M", time.localtime())
    # 开始时间
    dodo.start = time.time()
    bg_button["state"] = "disable"
    end_button["state"] = "normal"
    with open(f"{dodo.file_name}.txt", 'a') as f:
        f.write("hello world!!\n")
    dodo.m_l = mouse.Listener(on_move=dodo.on_move, on_scroll=dodo.on_m_scroll, on_click=dodo.on_m_click)
    dodo.k_l = keyboard.Listener(on_press=dodo.on_down, on_release=dodo.on_up)
    dodo.m_l.start()
    dodo.k_l.start()


def write_do():
    make_do()
    end_button["state"] = "normal"
    bg_button["state"] = "disable"


def write_end():
    dodo.m_l.stop()
    dodo.k_l.stop()
    end_button["state"] = "disable"
    bg_button["state"] = "normal"


bg_button = tkinter.Button(win, text="开始录制", font=("kaiti", 15), fg="blue", command=write_do)
end_button = tkinter.Button(win, text="结束录制", font=("kaiti", 15), fg="red", state="disable", command=write_end)
bg_do_button = tkinter.Button(win, text="开始执行", font=("kaiti", 15), command=do_it)
file_path_entry = tkinter.Entry(win, width=10, font=("kaiti", 18), state="disable")
select_file_entry = tkinter.Button(win, width=1, text="▼", font=("kaiti", 12), command=select_file)

bg_button.place(x=10, y=10)
end_button.place(x=152, y=10)
bg_do_button.place(x=152, y=50)
file_path_entry.place(x=10, y=56)
select_file_entry.place(x=115, y=56)

if __name__ == "__main__":
    win.mainloop()

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值