You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

按键与鼠标点击追踪代码故障求助:无法停止且无法写入Excel

问题分析与修复方案

核心问题原因

  1. 程序无法终止:仅修改is_running变量无法停止监听器,且原代码中mouse_listener.join()会先阻塞主线程,导致键盘监听器的终止逻辑无法触发后续流程。
  2. Excel无法写入:程序一直阻塞在监听器的join()步骤,根本没执行到workbook.save()代码,自然无法生成Excel文件。

修复后的代码

import time
import openpyxl
from pynput.mouse import Listener as MouseListener
from pynput.keyboard import Listener as KeyboardListener
from pynput.keyboard import Key

workbook = openpyxl.Workbook()
worksheet = workbook.active
worksheet.title = "InputData"
worksheet.append(["Time", "Event Type", "X", "Y", "Button/Key"])

input_count = 0
start_time = time.time()

# 保存监听器实例,方便后续停止
mouse_listener = None
keyboard_listener = None

def stop_listening():
    # 停止两个监听器
    if mouse_listener:
        mouse_listener.stop()
    if keyboard_listener:
        keyboard_listener.stop()

def record_input(event_type, x, y, action):
    global input_count
    input_count += 1
    current_time = time.time()
    worksheet.append([current_time, event_type, x, y, action])

def on_mouse_click(x, y, button, pressed):
    if pressed:
        event_type = "Mouse Click"
        action = f"Mouse {button} Pressed"
        record_input(event_type, x, y, action)
        print(f"Mouse clicked at ({x}, {y}) with {button}")

def on_key_press(key):
    event_type = "Key Press"
    try:
        action = f"Key Pressed: {key.char}"
        print(f"Key pressed: {key.char}")
        if key == Key.f12:  # 按F12停止程序
            print("F12已按下,程序即将终止...")
            stop_listening()
            return False  # 返回False终止键盘监听器
    except AttributeError:
        action = f"Special Key Pressed: {key}"
        print(f"Special key pressed: {key}")
        if key == Key.f12:
            print("F12已按下,程序即将终止...")
            stop_listening()
            return False
    record_input(event_type, None, None, action)

# 初始化监听器
mouse_listener = MouseListener(on_click=on_mouse_click)
keyboard_listener = KeyboardListener(on_press=on_key_press)

# 启动监听器
mouse_listener.start()
keyboard_listener.start()

# 等待两个监听器结束
keyboard_listener.join()
mouse_listener.join()

end_time = time.time()
time_elapsed = end_time - start_time
input_rate = input_count / time_elapsed
workbook.save("InputData.xlsx")
print(f"程序已结束,共记录{input_count}次输入,耗时{time_elapsed:.2f}秒,输入频率{input_rate:.2f}次/秒")

关键修改点

  • 保存监听器实例到全局变量,在stop_listening中调用stop()方法真正终止监听器
  • 在on_key_press中返回False,触发键盘监听器的终止逻辑
  • 调整监听器启动顺序,先启动再同时等待,避免单监听器阻塞主线程
  • 确保workbook.save()能被执行到,监听器终止后会自动走到后续代码

内容的提问来源于stack exchange,提问作者Kana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 05:53:24