用管理员权限
import tkinter as tk import json import time import pyautogui from pynput.keyboard import Key, Listener as KeyboardListener from pynput.mouse import Listener as MouseListener actions = [] class ActionRepeat: def __init__(self, actions): self.actions = actions self.now = actions[0]['time'] def repeat(self): nums=len(self.actions) index=1 for action in range(0,nums): if self.actions[action]['action'] == 'mouse_click': pyautogui.moveTo(self.actions[action]['x'], self.actions[action]['y']) pyautogui.click() elif self.actions[action]['action'] == 'key_press': key=self.actions[action]['key'].strip("'") if key.startswith('Key.'): key=key.split('.')[-1] pyautogui.keyDown(key) elif self.actions[action]['action'] == 'key_release': key = self.actions[action]['key'].strip("'") if key.startswith('Key.'): key = key.split('.')[-1] pyautogui.keyUp(key) self.latertime = time.time() if action<nums-1: wait_time = self.actions[action+index]['time'] - self.actions[action]['time'] print(self.actions[action]['action']) print(wait_time) # 由于系统延迟计数误差等,可能出现wait_time等于负值的情况 wait_time1 = max(0, wait_time) self.nowtime=time.time() time.sleep(wait_time1-(self.nowtime-self.latertime)) print(1) print(self.nowtime-self.latertime) print(1) self.latertime=time.time() # 初始化操作列表 def on_press(key): try: # 记录按键 actions.append({'time': time.time(), 'action': 'key_press', 'key': str(key.char)}) except AttributeError: # 特殊按键如Ctrl, Alt等 actions.append({'time': time.time(), 'action': 'key_press', 'key': str(key)}) def on_release(key): key=str(key) if key.startswith("'") and key.endswith("'"): key=key[1:-1] actions.append({'time': time.time(), 'action': 'key_release', 'key': str(key)}) def on_click(x, y, button, pressed): if pressed: # 记录鼠标点击 actions.append({'time': time.time(), 'action': 'mouse_click', 'button': str(button), 'x': x, 'y': y}) class ActionRecordApp(tk.Tk): def __init__(self): super().__init__() self.title('Action Recorder and Playback') #建立界面大小 self.geometry('396x390') #初始化times self.times=0 # 创建按钮 button_start = tk.Button(self, text='Start Recording', command=self.start_recording) button_stop = tk.Button(self, text='Stop Recording', command=self.stop_recording) button_playback = tk.Button(self, text='Playback', command=self.playback) #创建输入框 entry=tk.Entry(self,width=6) entry1=tk.Entry(self,width=8) self.entry=entry self.entry1=entry1 # 创建一个标签,用于显示输入的数字 label = tk.Label(self, text="次数") self.lable=label # 布局按钮 max_row = 2 max_column = 2 # weight=0,使对应行或列不会随窗口改变而改变,weight=1则表示可以扩展 for i in range(max_row + 1): self.rowconfigure(i, weight=0) for i in range(max_column + 1): self.columnconfigure(i, weight=0) # 很可能由于tinker预留框固定导致空行多,哈哈,自己界面设大了 button_start.grid(row=0, column=0) button_stop.grid(row=0, column=2) button_playback.grid(row=1, column=1) entry.grid(row=2,column=1) #通过绑定用户释放事件,后执行相应方法 entry.bind("<KeyRelease>",self.get_strings) entry1.grid(row=3,column=1) entry1.bind("<KeyRelease>",self.get_name) label.grid(row=2,column=0) # 创建键盘监听器 self.keyboard_listener = KeyboardListener(on_press=on_press, on_release=on_release) # 创建鼠标监听器 self.mouse_listener = MouseListener(on_click=on_click) self.actions = actions def get_name(self,event): #entry.get即是得到的信息 self.namefile=self.entry1.get() def get_strings(self,event): self.Get=self.entry.get() times=int(self.Get) self.times=times def start_recording(self): print("start") #self.begin=time.time() self.keyboard_listener.start() self.mouse_listener.start() def stop_recording(self): print("stop") #self.stop=time.time() self.keyboard_listener.stop() self.mouse_listener.stop() # self.keyboard_listener.join() # self.mouse_listener.join() print(self.actions) with open('D:/{}.json'.format(self.namefile), 'w') as f: json.dump(self.actions, f) self.actions = self.load_actions_from_file() def load_actions_from_file(self): with open('D:/{}.json'.format(self.namefile), 'r') as file: actions = json.load(file) return actions def playback(self): com = ActionRepeat(self.actions) if(self.times>0): for i in range(0,self.times): print("plaback") com.repeat() else: self.lable['text']="输入的需要大于0" # 防止模块导入时运行 if __name__ == '__main__': app = ActionRecordApp() app.mainloop()
不断地调试,发现不是系统误差,应该是pynpt库内部的时间误差,看来该结束了,最好还是利用底层的api