简单的按键模拟器

依赖:
pip install pynput
pip install pywin32

代码:

import tkinter as tk
import time
import json
from pynput.keyboard import Controller, Key, Listener
import win32gui
import threading


class KeyPressSimulator:
    def __init__(self, root, output_text):
        self.root = root
        self.output_text = output_text
        self.title = "按键模拟器"
        self.root.title(self.title)
        self.root.attributes("-topmost", True)
        self.root.geometry("600x400+640+360")
        self.name = ""
        self.name0_label = tk.Label(self.root, text="当前窗口:")
        self.name0_label.pack(pady=4)
        self.name_label = tk.Label(self.root, bg="lightgray")
        self.name_label.pack(pady=4)

        self.target0_label = tk.Label(self.root, text="目标窗口:")
        self.target0_label.pack(pady=4)
        self.target_label = tk.Label(self.root, bg="lightgray")
        self.target_label.pack(pady=4)

        self.delay_label = tk.Label(self.root, text=f"{'-' * 100}\n模拟延迟 (秒):")
        self.delay_label.pack(pady=4)

        self.delay_entry = tk.Entry(self.root)
        self.delay_entry.insert(tk.END, "1")
        self.delay_entry.pack(pady=5)

        self.key_label = tk.Label(self.root, text="模拟按键 (用英文逗号分隔):")
        self.key_label.pack(pady=4)

        self.key_entry = tk.Entry(self.root)
        self.key_entry.insert(tk.END, "a,b,c")
        self.key_entry.pack(pady=4)

        self.fr = tk.Frame(self.root)
        self.fr.pack(pady=5)

        self.confirm_button = tk.Button(self.fr, text="目标窗口(F6)", command=self.confirm)
        self.confirm_button.grid(row=0, column=0, padx=5, pady=5)

        self.start_button = tk.Button(self.fr, text="启动按键(F7)", command=self.start_simulation, state=tk.DISABLED)
        self.start_button.grid(row=1, column=0, padx=5, pady=5)

        self.stop_button = tk.Button(self.fr, text="停止按键(F8)", command=self.stop_simulation, state=tk.DISABLED)
        self.stop_button.grid(row=2, column=0, padx=5, pady=5)

        self.save_button = tk.Button(self.fr, text="保存设置", command=self.save_settings)
        self.save_button.grid(row=0, column=1, padx=5, pady=5)

        self.load_button = tk.Button(self.fr, text="读取设置", command=self.load_settings)
        self.load_button.grid(row=1, column=1, padx=5, pady=5)

        self.clear_button = tk.Button(self.fr, text="清除输出", command=self.clear_output)
        self.clear_button.grid(row=2, column=1, padx=5, pady=5)

        self.root.protocol("WM_DELETE_WINDOW", self.on_closing)

        self.keyboard = Controller()
        self.simulating = False
        self.keys_to_press = []
        self.current_key_index = 0

        self.rep_name()
        self.print_to_output("首先确定目标窗口,然后点击启动。\n活动窗口非目标窗口不工作。")

    def confirm(self):
        name = self.name
        if name:
            if name != self.title:
                self.print_to_output(f"锁定窗口: {name}")
                self.start_button.config(state=tk.NORMAL)
                self.stop_button.config(state=tk.DISABLED)
                self.confirm_button.config(state=tk.DISABLED)
                self.target_label.config(text=name)
            else:
                self.print_to_output("不能锁定本程序窗口")
        else:
            self.print_to_output("未能获取到窗口句柄")

    def rep_name(self):
        title = win32gui.GetWindowText(win32gui.GetForegroundWindow())
        if title:
            if title != self.title:
                self.name = title
            self.name_label.config(text=title)
        self.root.after(200, self.rep_name)

    def start_simulation(self):
        try:
            delay = float(self.delay_entry.get())
            if delay <= 0:
                raise ValueError("延迟必须大于0")
        except ValueError:
            self.print_to_output("无效的延迟值,请输入正数")
            return

        keys = self.key_entry.get()
        if not keys:
            self.print_to_output("请输入需要模拟的按键")
            return

        self.clear_output()
        self.simulating = True
        self.keys_to_press = [key.strip() for key in keys.split(',')]
        self.current_key_index = 0

        self.start_button.config(state=tk.DISABLED)
        self.stop_button.config(state=tk.NORMAL)
        self.confirm_button.config(state=tk.DISABLED)
        self.simulate_key_press()

    def stop_simulation(self):
        self.simulating = False
        self.start_button.config(state=tk.NORMAL)
        self.stop_button.config(state=tk.DISABLED)
        self.confirm_button.config(state=tk.NORMAL)

    def simulate_key_press(self):
        if self.simulating:
            delay = float(self.delay_entry.get())
            if self.target_label.cget("text") == self.name_label.cget("text"):
                if self.keys_to_press:
                    key_to_press = self.keys_to_press[self.current_key_index]
                    self.keyboard.press(key_to_press)
                    time.sleep(0.1)
                    self.keyboard.release(key_to_press)
                    self.print_to_output(f"模拟按键: {key_to_press},延迟: {delay}秒")
                    self.current_key_index = (self.current_key_index + 1) % len(self.keys_to_press)
            self.root.after(int(delay * 1000), self.simulate_key_press)

    def save_settings(self):
        settings = {"keys": self.key_entry.get(), "delay": self.delay_entry.get()}
        try:
            with open("按键机设置.json", "w") as json_file:
                json.dump(settings, json_file)
            self.print_to_output("设置已保存")
        except Exception as e:
            self.print_to_output(f"保存设置失败:{e}")

    def load_settings(self):
        try:
            with open("按键机设置.json", "r") as json_file:
                settings = json.load(json_file)
                self.key_entry.delete(0, tk.END)
                self.key_entry.insert(tk.END, settings["keys"])
                self.delay_entry.delete(0, tk.END)
                self.delay_entry.insert(tk.END, settings["delay"])
                self.print_to_output("设置已加载")
        except FileNotFoundError:
            self.print_to_output("没有找到保存的设置文件")
        except json.JSONDecodeError:
            self.print_to_output("配置文件格式错误")
        except Exception as e:
            self.print_to_output(f"加载设置失败:{e}")

    def print_to_output(self, text):
        self.output_text.insert(tk.END, text + "\n")
        self.output_text.yview(tk.END)

    def on_closing(self):
        self.stop_simulation()
        self.root.destroy()

    def clear_output(self):
        self.output_text.delete(1.0, tk.END)


def start_key_listener():
    def on_press(key):
        if key == Key.f6:
            app.confirm()
        elif key == Key.f7:
            app.start_simulation()
        elif key == Key.f8:
            app.stop_simulation()

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

if __name__ == "__main__":
    rt = tk.Tk()
    out_text = tk.Text(rt, width=50, height=30)
    out_text.pack(side=tk.RIGHT, padx=10, pady=10)
    app = KeyPressSimulator(rt, out_text)

    listener_thread = threading.Thread(target=start_key_listener, daemon=True)
    listener_thread.start()

    rt.mainloop()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值