Hi,聆听·彼岸



听说,你是我最遥不可及的梦。
What should I do?
What should I do?
I think I'm going to fall in love with myself.

Python操作键鼠与剪贴板

发表于 2022-10-23| 分类于 笔记 | | 评论数

Python模拟按键

可以调用win32api来实现

# pip install pypiwin32 
# coding=utf-8
import win32con
import win32api
import time
key_map = {
    "0": 49, "1": 50, "2": 51, "3": 52, "4": 53, "5": 54, "6": 55, "7": 56, "8": 57, "9": 58,
    "A": 65, "B": 66, "C": 67, "D": 68, "E": 69, "F": 70, "G": 71, "H": 72, "I": 73, "J": 74,
    "K": 75, "L": 76, "M": 77, "N": 78, "O": 79, "P": 80, "Q": 81, "R": 82, "S": 83, "T": 84,
    "U": 85, "V": 86, "W": 87, "X": 88, "Y": 89, "Z": 90
}
 
 
def key_down(key):
    """
    函数功能:按下按键
    参    数:key:按键值
    """
    key = key.upper()
    vk_code = key_map[key]
    win32api.keybd_event(vk_code,win32api.MapVirtualKey(vk_code,0),0,0)
 
 
def key_up(key):
    """
    函数功能:抬起按键
    参    数:key:按键值
    """
    key = key.upper()
    vk_code = key_map[key]
    win32api.keybd_event(vk_code, win32api.MapVirtualKey(vk_code, 0), win32con.KEYEVENTF_KEYUP, 0)
 
 
def key_press(key):
    """
    函数功能:点击按键(按下并抬起)
    参    数:key:按键值
    """
    key_down(key)
    time.sleep(0.02)
    key_up(key)

def move(x, y):
"""
函数功能:移动鼠标到指定位置
参 数:x:x坐标
y:y坐标
"""
win32api.SetCursorPos((x, y))


def get_cur_pos():
"""
函数功能:获取当前鼠标坐标
"""
p={"x":0,"y":0}
pos = win32gui.GetCursorPos()
p['x']=pos[0]
p['y']=pos[1]
return p


def left_click():
"""
函数功能:鼠标左键点击
"""
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN | win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)


def right_click():
"""
函数功能:鼠标右键点击
"""
win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTDOWN | win32con.MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0)


def left_down():
"""
函数功能:鼠标左键按下
"""
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)


def left_up():
"""
函数功能:鼠标左键抬起
"""
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)


def right_down():
"""
函数功能:鼠标右键按下
"""
win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0)


def right_up():
"""
函数功能:鼠标右键抬起
"""
win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0)

# 以上代码来自脚本之家

也有用ctypes库的——可以调用dll

最后我看到了pykeyboard和pymouse,继续看,直接大一统PyUserInput

PyUserInput

安装

pip install pywin32 -i https://pypi.tuna.tsinghua.edu.cn/simple

是的,到这里,我兴致冲冲的安装了pywin32搜一下pyhook的安装,说什么不能用pip安装。
pyhook与Python3不兼容,要安装pyhook3。看到这里我就知道有问题了,赶紧去翻了翻PyUserInput的源代码。
最后在readme中找到了这样一段话

Deprecated
Please use Pynput instead.

What’s wrong with PyUserInput?

  • Nobody is actively working on it
  • Events on Windows depend on PyHook which is dead and not compatible with Python 3
  • Only works with QWERTY
  • Inconsistent API for non-printable characters
  • Probably more

好吧!生活总是一波三折的。

Pynput

pip install pynput -i https://pypi.tuna.tsinghua.edu.cn/simple 

再翻译一下官方文档

控制鼠标

像这样使用:pynput.mouse.Controller

from pynput.mouse import Button, Controller

mouse = Controller()

# 读取鼠标位置
print('The current pointer position is {0}'.format(
mouse.position))

# 移动鼠标
mouse.position = (10, 20)
print('Now we have moved it to {0}'.format(
mouse.position))

# 相对于当前位置移动鼠标
mouse.move(5, -5)

# 按下和松开鼠标左键
mouse.press(Button.left)
mouse.release(Button.left)

# 双击
mouse.click(Button.left, 2)

# 0向下滚动两步,1向上(官方指的是(水平滚动,垂直滚动))
mouse.scroll(0, 2)

监听鼠标

像这样使用:pynput.mouse.Listener

from pynput import mouse

# 监听鼠标移动事件
def on_move(x, y):
print('Pointer moved to {0}'.format(
(x, y)))

# 监听鼠标单击事件
def on_click(x, y, button, pressed):
print('{0} at {1}'.format(
'Pressed' if pressed else 'Released',
(x, y)))
if not pressed:
# 停止监听
return False

# 监听鼠标滚动事件
def on_scroll(x, y, dx, dy):
print('Scrolled {0} at {1}'.format(
'down' if dy < 0 else 'up',
(x, y)))

# 开始监听直到停止监听
with mouse.Listener(
on_move=on_move,
on_click=on_click,
on_scroll=on_scroll) as listener:
listener.join()

# 非阻塞式监听
listener = mouse.Listener(
on_move=on_move,
on_click=on_click,
on_scroll=on_scroll)
listener.start()
# input() 彩蛋
# 使用上面的非阻塞版本时,当前线程将继续执行。在与包含主循环的其他 GUI 框架集成时,这可能是必需的,但是当从脚本运行时,这将导致程序立即终止。

翻累了。。。
监听器

__init__(on_move=无,on_click=无,on_scroll=无,抑制=假,**kwargs)[来源]
应始终使用关键字参数调用此构造函数。参数包括:

组应为“无”;保留用于在实现线程组类时将来的扩展。

目标是要由 run() 方法调用的可调用对象。默认为“无”,表示不调用任何内容。

名称是线程名称。默认情况下,唯一名称由“Thread-N”形式构造,其中 N 是一个小的十进制数。

args 是目标调用的参数元组。默认值为 ()。

kwargs 是目标调用的关键字参数的字典。默认值为 {}。

如果子类重写了构造函数,则必须确保在对线程执行任何其他操作之前调用基类构造函数 (Thread.__init__())。

running
侦听器当前是否正在运行。

start()
启动线程的活动。

每个线程对象最多只能调用一次。它安排在单独的控制线程中调用对象的 run() 方法。

如果在同一线程对象上多次调用,则此方法将引发运行时错误。

stop()
停止侦听事件。

此方法返回时,将不再传递任何事件。调用此方法后,侦听器实例将无法再使用,因为侦听器是 ,一旦停止,就无法重新启动。threading.Thread

若要恢复对事件的侦听,必须创建新的侦听器。

wait()
等待此侦听器准备就绪。

控制键盘

像这样使用:pynput.keyboard.Controller

from pynput.keyboard import Key, Controller

keyboard = Controller()

# 按下和松开space键
keyboard.press(Key.space)
keyboard.release(Key.space)

# Type a lower case A; this will work even if no key on the
# physical keyboard is labelled 'A'
keyboard.press('a')
keyboard.release('a')

# Type two upper case As
keyboard.press('A')
keyboard.release('A')
with keyboard.pressed(Key.shift):
keyboard.press('a')
keyboard.release('a')

# Type 'Hello World' using the shortcut type method
keyboard.type('Hello World')

# 查看按键
print(dir(Key))

监听键盘

像这样使用:pynput.keyboard.Listener

from pynput import keyboard

def on_press(key):
try:
print('alphanumeric key {0} pressed'.format(
key.char))
except AttributeError:
print('special key {0} pressed'.format(
key))

def on_release(key):
print('{0} released'.format(
key))
if key == keyboard.Key.esc:
# Stop listener
return False

# Collect events until released
with keyboard.Listener(
on_press=on_press,
on_release=on_release) as listener:
listener.join()

# ...or, in a non-blocking fashion:
listener = keyboard.Listener(
on_press=on_press,
on_release=on_release)
listener.start()

具体参考鼠标,这里不再翻译
官方文档还有很多有用的东西,这里不再赘述。比如tap(按下并释放一个键)。
官方文档

Python控制剪切板

import pyperclip

# 复制文本
pyperclip.copy('The text to be copied to the clipboard.')
# 取剪贴板文本
pyperclip.paste()


# 此函数调用会一直阻塞,直到剪贴板上存在一个新的文本字符串,该字符串与首次调用该函数时的文本不同。它返回此文本。
waitForNewPaste(timeout=None)
此函数调用将阻塞,直到剪贴板上存在非空文本字符串。它返回此文本。
waitForPaste(timeout=None)

实例
按下f7模拟鼠标左键单击

from pynput import mouse
from pynput import keyboard
from pynput.keyboard import Key
from pynput.mouse import Button

mousec = mouse.Controller()

def on_press(key):
try:
print('alphanumeric key {0} pressed'.format(
key.char))
except AttributeError:
print('special key {0} pressed'.format(
key))
if key == Key.f7 :
mousec.press(Button.left)
mousec.release(Button.left)

with keyboard.Listener(
on_press=on_press) as listener:
listener.join()


满分是10分的话,这篇文章你给几分,您的支持将鼓励我继续创作!