python-script-library/x时间后按下x按键.py

177 lines
7.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import time
import threading
from pynput import keyboard
from pynput.keyboard import Key, Controller
class AutoKeyPresser:
# =============== 全局配置 ===============
CONTROL_KEY = 'p' # 控制定时器启动/暂停的快捷键
TARGET_KEY = Key.f10 # 要自动按下的目标键默认为F10
INTERVAL = 60 + 52 # 定时器间隔时间1分钟52秒 = 112秒
# =============== 结束配置 ===============
def __init__(self):
self.timer = None
self.is_active = False
self.listener = None
self.keyboard_controller = Controller()
self.ignore_next_key = False # 标志位,用于忽略程序自动按下的目标键
self.timer_lock = threading.Lock() # 线程锁确保状态同步
self.last_activity_time = 0 # 记录最后一次活动时间
def simulate_key_press(self):
"""模拟按下配置的目标键"""
try:
self.ignore_next_key = True # 设置标志,忽略接下来的目标键事件
# 使用正确的键模拟
self.keyboard_controller.press(self.TARGET_KEY)
time.sleep(0.05) # 短暂延迟模拟真实按键
self.keyboard_controller.release(self.TARGET_KEY)
current_time = time.strftime("%Y-%m-%d %H:%M:%S")
key_name = self._get_key_name(self.TARGET_KEY)
print(f"[{current_time}] 已自动按下 {key_name}")
except Exception as e:
print(f"模拟按下 {self._get_key_name(self.TARGET_KEY)} 时发生错误: {e}")
def _get_key_name(self, key):
"""获取按键的可读名称"""
if hasattr(key, 'name'):
return key.name.upper()
elif hasattr(key, 'char'):
return key.char.upper()
return str(key)
def start_timer(self):
"""启动定时器总是重新开始112秒计时"""
with self.timer_lock:
if self.is_active:
return
self.is_active = True
self.last_activity_time = time.time() # 重置开始时间
current_time = time.strftime("%Y-%m-%d %H:%M:%S")
key_name = self._get_key_name(self.TARGET_KEY)
print(f"[{current_time}] 定时器已启动,将在{self.INTERVAL}秒后按下 {key_name}")
print(f"{self.CONTROL_KEY.upper()} 键可以暂停定时器")
def timer_loop():
# 记录本次循环的开始时间
cycle_start_time = time.time()
while self.is_active:
# 计算已经过去的时间
elapsed_time = time.time() - cycle_start_time
remaining_time = self.INTERVAL - elapsed_time
# 如果已经达到或超过间隔时间,执行按键操作
if remaining_time <= 0:
if self.is_active: # 再次检查状态
self.simulate_key_press()
# 重置循环开始时间,开始新的周期
cycle_start_time = time.time()
continue
# 分段等待,便于及时响应暂停命令
wait_interval = min(0.5, remaining_time) # 每次最多等待0.5秒
if wait_interval > 0:
time.sleep(wait_interval)
self.timer = threading.Thread(target=timer_loop)
self.timer.daemon = True
self.timer.start()
def pause_timer(self):
"""暂停定时器"""
with self.timer_lock:
if not self.is_active:
return
self.is_active = False
current_time = time.strftime("%Y-%m-%d %H:%M:%S")
# 计算已过去的时间(用于显示信息)
if self.last_activity_time > 0:
elapsed = time.time() - self.last_activity_time
remaining = max(0, self.INTERVAL - elapsed)
print(f"[{current_time}] 定时器已暂停(已等待{elapsed:.1f}秒,剩余{remaining:.1f}秒)")
else:
print(f"[{current_time}] 定时器已暂停")
def on_press(self, key):
"""键盘按键事件处理"""
try:
# 检测控制键按下,用于控制定时器暂停/恢复
if hasattr(key, 'char') and (key.char.lower() == self.CONTROL_KEY.lower()):
if not self.is_active:
# 按下控制键,启动定时器(重新开始计时)
self.start_timer()
else:
# 定时器运行中按下控制键,暂停定时器
self.pause_timer()
# 处理Esc键事件 - 不再退出程序,只显示信息
elif key == Key.esc:
current_time = time.strftime("%Y-%m-%d %H:%M:%S")
status = '运行中' if self.is_active else '已暂停'
print(f"[{current_time}] 检测到按下Esc键定时器状态{status}")
print("提示Esc键已禁用退出功能程序继续运行")
# 处理目标键事件(仅用于显示,不影响定时器状态)
elif key == self.TARGET_KEY:
if self.ignore_next_key:
# 如果是程序自动按下的键,忽略它
self.ignore_next_key = False
else:
# 用户手动按下的目标键,只显示信息不影响定时器
current_time = time.strftime("%Y-%m-%d %H:%M:%S")
status = '运行中' if self.is_active else '已暂停'
key_name = self._get_key_name(self.TARGET_KEY)
print(f"[{current_time}] 检测到手动按下 {key_name} 键(定时器状态:{status}")
except AttributeError:
# 处理特殊功能键没有char属性的键
if key == Key.esc:
current_time = time.strftime("%Y-%m-%d %H:%M:%S")
status = '运行中' if self.is_active else '已暂停'
print(f"[{current_time}] 检测到按下Esc键定时器状态{status}")
print("提示Esc键已禁用退出功能程序继续运行")
elif key == self.TARGET_KEY:
if self.ignore_next_key:
self.ignore_next_key = False
else:
current_time = time.strftime("%Y-%m-%d %H:%M:%S")
status = '运行中' if self.is_active else '已暂停'
key_name = self._get_key_name(self.TARGET_KEY)
print(f"[{current_time}] 检测到手动按下 {key_name} 键(定时器状态:{status}")
def on_release(self, key):
"""键盘释放事件处理 - 移除Esc键退出功能"""
pass
def start_listening(self):
"""开始监听键盘事件"""
key_name = self._get_key_name(self.TARGET_KEY)
print(f"{key_name}自动按下程序已启动")
print(f"{self.CONTROL_KEY.upper()} 键开始定时器,再次按 {self.CONTROL_KEY.upper()} 键暂停定时器")
print(f"定时器间隔时间:{self.INTERVAL}")
print(f"目标按键:{key_name}")
print("提示:定时器暂停后重新启动将重新开始计时")
print("提示Esc键退出功能已禁用如需退出程序请使用Ctrl+C")
# 同时监听按下和释放事件
with keyboard.Listener(on_press=self.on_press, on_release=self.on_release) as self.listener:
try:
self.listener.join()
except Exception as e:
print(f"监听器错误: {e}")
if __name__ == "__main__":
try:
auto_presser = AutoKeyPresser()
auto_presser.start_listening()
except KeyboardInterrupt:
print("\n程序被用户中断Ctrl+C")
except Exception as e:
print(f"程序运行错误: {e}")