如何用Python案例实现鼠标控制?

wen python案例 2

本文目录导读:

如何用Python案例实现鼠标控制?

  1. 使用 pyautogui 库(推荐)
  2. 使用 pynput 库
  3. 使用 ctypes 库(Windows系统)
  4. 综合应用:自动截图工具
  5. 注意事项

我来为你详细介绍几种用Python实现鼠标控制的方法,并提供完整案例。

使用 pyautogui 库(推荐)

安装

pip install pyautogui

基础控制案例

import pyautogui
import time
# 获取屏幕尺寸
screen_width, screen_height = pyautogui.size()
print(f"屏幕尺寸: {screen_width}x{screen_height}")
# 获取鼠标当前位置
current_x, current_y = pyautogui.position()
print(f"当前鼠标位置: ({current_x}, {current_y})")
# 移动鼠标到指定位置(绝对坐标)
pyautogui.moveTo(500, 300, duration=1)  # 1秒内移动到(500,300)
time.sleep(0.5)
# 相对移动鼠标
pyautogui.moveRel(100, 0, duration=0.5)  # 向右移动100像素
# 鼠标点击
pyautogui.click(200, 200)  # 在(200,200)位置点击
pyautogui.click(button='right')  # 右键点击
pyautogui.doubleClick(300, 300)  # 双击
pyautogui.tripleClick(400, 400)  # 三击
# 拖拽操作
pyautogui.drag(0, 200, duration=0.5)  # 向下拖拽200像素
pyautogui.dragTo(500, 200, duration=0.5)  # 拖拽到指定位置
# 滚动操作
pyautogui.scroll(-5)  # 向下滚动5格
pyautogui.scroll(5)   # 向上滚动5格

高级案例:自动画图程序

import pyautogui
import math
import time
def draw_circle(center_x, center_y, radius, duration=0.01):
    """在屏幕上画圆"""
    # 移动到起始点
    pyautogui.moveTo(center_x + radius, center_y)
    pyautogui.mouseDown()  # 按下鼠标
    # 画圆
    for i in range(361):  # 360度完整圆
        angle = math.radians(i)
        x = center_x + radius * math.cos(angle)
        y = center_y + radius * math.sin(angle)
        pyautogui.moveTo(x, y, duration=duration)
    pyautogui.mouseUp()  # 松开鼠标
def draw_spiral():
    """画螺旋线"""
    pyautogui.moveTo(400, 400)
    pyautogui.mouseDown()
    for i in range(0, 500, 5):
        angle = math.radians(i)
        x = 400 + i * 0.5 * math.cos(angle)
        y = 400 + i * 0.5 * math.sin(angle)
        pyautogui.moveTo(x, y, duration=0.001)
    pyautogui.mouseUp()
# 使用示例
time.sleep(3)  # 给你3秒时间切换到绘图软件
draw_circle(500, 400, 200)
time.sleep(1)
draw_spiral()

使用 pynput 库

安装

pip install pynput

鼠标控制案例

from pynput.mouse import Button, Controller
import time
# 创建鼠标控制器
mouse = Controller()
# 获取鼠标位置
print(f"当前鼠标位置: {mouse.position}")
# 移动鼠标到指定位置
mouse.position = (500, 300)
time.sleep(0.5)
# 相对移动
mouse.move(100, 50)  # 向右移动100,向下移动50
# 点击操作
mouse.click(Button.left, 1)  # 左键单击
mouse.click(Button.right, 2)  # 右键双击
mouse.click(Button.middle, 1)  # 中键单击
# 按下和松开鼠标
mouse.press(Button.left)
time.sleep(0.5)
mouse.release(Button.left)
# 滚动操作
mouse.scroll(0, -5)  # 向下滚动5行
mouse.scroll(0, 5)   # 向上滚动5行

鼠标监听和自动化结合

from pynput.mouse import Button, Controller, Listener
import threading
class MouseController:
    def __init__(self):
        self.mouse = Controller()
        self.recording = False
        self.recorded_actions = []
    def on_click(self, x, y, button, pressed):
        """鼠标点击监听回调"""
        if self.recording:
            action = {
                'type': 'click',
                'x': x,
                'y': y,
                'button': str(button),
                'pressed': pressed
            }
            self.recorded_actions.append(action)
            print(f"记录点击: ({x}, {y}) - {button}")
    def on_move(self, x, y):
        """鼠标移动监听回调"""
        if self.recording and len(self.recorded_actions) > 0:
            pass  # 可以记录移动轨迹
    def start_recording(self):
        """开始记录鼠标动作"""
        self.recording = True
        self.recorded_actions = []
        print("开始记录鼠标动作...")
    def stop_recording(self):
        """停止记录鼠标动作"""
        self.recording = False
        print(f"停止记录,共记录 {len(self.recorded_actions)} 个动作")
    def replay_actions(self):
        """回放记录的鼠标动作"""
        print("开始回放...")
        for action in self.recorded_actions:
            if action['type'] == 'click':
                x, y = action['x'], action['y']
                self.mouse.position = (x, y)
                if 'left' in action['button']:
                    button = Button.left
                elif 'right' in action['button']:
                    button = Button.right
                else:
                    button = Button.middle
                if action['pressed']:
                    self.mouse.press(button)
                else:
                    self.mouse.release(button)
            time.sleep(0.1)  # 添加延迟使回放更自然
        print("回放完成!")
# 使用示例
def main():
    controller = MouseController()
    # 启动监听器
    listener = Listener(
        on_click=controller.on_click,
        on_move=controller.on_move
    )
    listener.start()
    # 模拟操作
    print("准备记录...")
    time.sleep(2)
    # 开始记录
    controller.start_recording()
    # 执行一些操作(实际中你会手动操作)
    print("现在移动鼠标并点击,按Ctrl+C停止")
    try:
        time.sleep(10)  # 等待10秒记录
    except KeyboardInterrupt:
        pass
    controller.stop_recording()
    # 回放记录的操作
    controller.replay_actions()
    listener.stop()
if __name__ == "__main__":
    main()

使用 ctypes 库(Windows系统)

import ctypes
import time
class MouseControl:
    def __init__(self):
        # 模拟鼠标事件
        self.MOUSEEVENTF_LEFTDOWN = 0x0002
        self.MOUSEEVENTF_LEFTUP = 0x0004
        self.MOUSEEVENTF_MIDDLEDOWN = 0x0020
        self.MOUSEEVENTF_MIDDLEUP = 0x0040
        self.MOUSEEVENTF_RIGHTDOWN = 0x0008
        self.MOUSEEVENTF_RIGHTUP = 0x0010
        self.MOUSEEVENTF_MOVE = 0x0001
        self.MOUSEEVENTF_ABSOLUTE = 0x8000
        self.MOUSEEVENTF_WHEEL = 0x0800
    def get_screen_size(self):
        """获取屏幕尺寸"""
        user32 = ctypes.windll.user32
        return user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)
    def move_to(self, x, y):
        """移动鼠标到指定位置(绝对坐标)"""
        screen_width, screen_height = self.get_screen_size()
        # 转换为绝对坐标(0-65535)
        abs_x = int(x * 65535 / screen_width)
        abs_y = int(y * 65535 / screen_height)
        ctypes.windll.user32.SetCursorPos(x, y)
        return True
    def click(self, x=None, y=None, button='left'):
        """点击操作"""
        if x is not None and y is not None:
            self.move_to(x, y)
            time.sleep(0.1)
        if button == 'left':
            ctypes.windll.user32.mouse_event(self.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
            time.sleep(0.05)
            ctypes.windll.user32.mouse_event(self.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
        elif button == 'right':
            ctypes.windll.user32.mouse_event(self.MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0)
            time.sleep(0.05)
            ctypes.windll.user32.mouse_event(self.MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0)
        elif button == 'middle':
            ctypes.windll.user32.mouse_event(self.MOUSEEVENTF_MIDDLEDOWN, 0, 0, 0, 0)
            time.sleep(0.05)
            ctypes.windll.user32.mouse_event(self.MOUSEEVENTF_MIDDLEUP, 0, 0, 0, 0)
        return True
    def double_click(self, x=None, y=None):
        """双击操作"""
        self.click(x, y, 'left')
        time.sleep(0.1)
        self.click(x, y, 'left')
    def drag(self, start_x, start_y, end_x, end_y):
        """拖拽操作"""
        self.move_to(start_x, start_y)
        time.sleep(0.1)
        # 按下左键
        ctypes.windll.user32.mouse_event(self.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
        # 缓慢移动到目标位置
        steps = 20
        for i in range(1, steps + 1):
            x = start_x + (end_x - start_x) * i // steps
            y = start_y + (end_y - start_y) * i // steps
            self.move_to(x, y)
            time.sleep(0.01)
        # 松开左键
        ctypes.windll.user32.mouse_event(self.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
# 使用示例
def main():
    mouse = MouseControl()
    # 获取屏幕尺寸
    width, height = mouse.get_screen_size()
    print(f"屏幕尺寸: {width}x{height}")
    # 移动鼠标
    mouse.move_to(width // 2, height // 2)
    time.sleep(0.5)
    # 点击操作
    mouse.click(100, 100, 'left')
    time.sleep(0.5)
    mouse.click(200, 200, 'right')
    # 双击
    mouse.double_click(300, 300)
    # 拖拽
    mouse.drag(400, 400, 500, 500)
if __name__ == "__main__":
    main()

综合应用:自动截图工具

import pyautogui
import tkinter as tk
from tkinter import messagebox
import threading
import time
class AutoScreenshotTool:
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("自动截图工具")
        self.root.geometry("400x300")
        # 截图区域设置
        self.start_x = tk.StringVar(value="100")
        self.start_y = tk.StringVar(value="100")
        self.width = tk.StringVar(value="800")
        self.height = tk.StringVar(value="600")
        self.interval = tk.StringVar(value="5")
        self.setup_ui()
    def setup_ui(self):
        # 坐标设置
        tk.Label(self.root, text="开始X:").grid(row=0, column=0, padx=5, pady=5)
        tk.Entry(self.root, textvariable=self.start_x).grid(row=0, column=1)
        tk.Label(self.root, text="开始Y:").grid(row=1, column=0, padx=5, pady=5)
        tk.Entry(self.root, textvariable=self.start_y).grid(row=1, column=1)
        tk.Label(self.root, text="宽度:").grid(row=2, column=0, padx=5, pady=5)
        tk.Entry(self.root, textvariable=self.width).grid(row=2, column=1)
        tk.Label(self.root, text="高度:").grid(row=3, column=0, padx=5, pady=5)
        tk.Entry(self.root, textvariable=self.height).grid(row=3, column=1)
        # 间隔设置
        tk.Label(self.root, text="间隔(秒):").grid(row=4, column=0, padx=5, pady=5)
        tk.Entry(self.root, textvariable=self.interval).grid(row=4, column=1)
        # 按钮
        tk.Button(self.root, text="开始自动截图", command=self.start_screenshot, 
                 bg="green", fg="white").grid(row=5, column=0, columnspan=2, pady=20)
        tk.Button(self.root, text="鼠标定位", command=self.get_mouse_position,
                 bg="blue", fg="white").grid(row=6, column=0, columnspan=2)
        # 状态显示
        self.status_label = tk.Label(self.root, text="就绪")
        self.status_label.grid(row=7, column=0, columnspan=2, pady=10)
    def get_mouse_position(self):
        """获取当前鼠标位置"""
        time.sleep(2)  # 给你2秒时间移动鼠标
        x, y = pyautogui.position()
        self.status_label.config(text=f"鼠标位置: ({x}, {y})")
        return x, y
    def take_screenshot(self):
        """截图功能"""
        try:
            x = int(self.start_x.get())
            y = int(self.start_y.get())
            w = int(self.width.get())
            h = int(self.height.get())
            # 移动鼠标到截图区域
            pyautogui.moveTo(x, y)
            time.sleep(0.5)
            # 截图
            screenshot = pyautogui.screenshot(region=(x, y, w, h))
            # 保存截图
            timestamp = time.strftime("%Y%m%d_%H%M%S")
            filename = f"screenshot_{timestamp}.png"
            screenshot.save(filename)
            print(f"已保存: {filename}")
            self.root.after(0, lambda: self.status_label.config(
                text=f"已保存: {filename}"))
        except Exception as e:
            print(f"截图失败: {e}")
    def start_screenshot(self):
        """开始自动截图"""
        try:
            interval = int(self.interval.get())
            def screenshot_loop():
                count = 0
                while count < 5:  # 截图5次
                    self.take_screenshot()
                    time.sleep(interval)
                    count += 1
                self.root.after(0, lambda: self.status_label.config(
                    text="截图完成"))
            # 在新线程中运行
            thread = threading.Thread(target=screenshot_loop)
            thread.daemon = True
            thread.start()
        except Exception as e:
            messagebox.showerror("错误", f"请检查输入: {e}")
    def run(self):
        self.root.mainloop()
if __name__ == "__main__":
    app = AutoScreenshotTool()
    app.run()

注意事项

  1. 安全控制:pyautogui有安全保护,快速将鼠标移到角落会触发异常
  2. 权限问题:某些系统可能需要管理员权限
  3. 多显示器:注意多显示器环境下的坐标处理
  4. 性能考虑:频繁操作可能影响系统性能
  5. 后台运行:程序运行时最好保持窗口在前台

这些案例涵盖了从基础到高级的鼠标控制方法,你可以根据实际需求选择合适的库和实现方式。

抱歉,评论功能暂时关闭!