鱼C论坛

 找回密码
 立即注册
查看: 139|回复: 8

[已解决]键盘精灵

[复制链接]
发表于 2024-4-23 21:16:43 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
想做一个键盘精灵
主要功能是,输入监听键A,和映射键B
达到的效果:当点击开始运行按钮后,敲击键A,实际等于在敲键B


  1. import tkinter as tk
  2. from pynput.keyboard import Controller, Listener, Key

  3. class KeyMapperApp:
  4.     def __init__(self, root):
  5.         self.root = root
  6.         self.root.title("键盘映射器")

  7.         # 设置UI界面
  8.         self.setup_ui()

  9.         # 初始化键盘控制器和监听器
  10.         self.keyboard = Controller()
  11.         self.listener = None

  12.     def setup_ui(self):
  13.         # 创建标签和输入框
  14.         tk.Label(self.root, text="监听键:").grid(row=0, column=0)
  15.         self.listen_key_entry = tk.Entry(self.root)
  16.         self.listen_key_entry.grid(row=0, column=1)

  17.         tk.Label(self.root, text="映射键:").grid(row=1, column=0)
  18.         self.map_key_entry = tk.Entry(self.root)
  19.         self.map_key_entry.grid(row=1, column=1)

  20.         # 创建按钮
  21.         tk.Button(self.root, text="开始运行", command=self.start_mapping).grid(row=2, column=0)
  22.         tk.Button(self.root, text="退出", command=self.stop_mapping).grid(row=2, column=1)

  23.     def start_mapping(self):
  24.         self.listen_key = self.listen_key_entry.get()
  25.         self.map_key = self.map_key_entry.get()

  26.         # 启动键盘监听
  27.         self.listener = Listener(on_press=self.on_press)
  28.         self.listener.start()
  29.         print('开始监听了')

  30.     def stop_mapping(self):
  31.         if self.listener:
  32.             self.listener.stop()
  33.         self.root.quit()

  34.     def on_press(self, key):
  35.         if hasattr(key, 'char') and key.char == self.listen_key:
  36.             print(self.listen_key)
  37.             self.keyboard.press(Key.backspace)
  38.             self.keyboard.release(Key.backspace)
  39.             self.keyboard.type(self.map_key)
  40.             self.keyboard.press(Key.tab)
  41.             self.keyboard.release(Key.tab)

  42. if __name__ == "__main__":
  43.     root = tk.Tk()
  44.     app = KeyMapperApp(root)
  45.     root.mainloop()
复制代码

Snipaste_2024-04-23_21-13-49.jpg
最佳答案
2024-4-24 11:06:42
我试了你的代码没有问题呀

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-4-23 21:18:05 | 显示全部楼层
你的代码基本上是正确的,只是在键盘精灵的逻辑上有一点小问题。当监听到按下的键是你设定的监听键时,你用键盘控制器执行了退格和输入映射键的操作,但是缺少了释放按键的操作。这会导致输入的映射键不会生效。

另外,在`if __name__ == "__main__":`部分,你应该将`app`对象传给`root.mainloop()`函数,而不是仅传入`root`。这样才能确保应用程序正常运行。

下面是修复了上述问题的代码:

  1. import tkinter as tk
  2. from pynput.keyboard import Controller, Listener, Key

  3. class KeyMapperApp:
  4.     def __init__(self, root):
  5.         self.root = root
  6.         self.root.title("键盘映射器")

  7.         # 设置UI界面
  8.         self.setup_ui()

  9.         # 初始化键盘控制器和监听器
  10.         self.keyboard = Controller()
  11.         self.listener = None

  12.     def setup_ui(self):
  13.         # 创建标签和输入框
  14.         tk.Label(self.root, text="监听键:").grid(row=0, column=0)
  15.         self.listen_key_entry = tk.Entry(self.root)
  16.         self.listen_key_entry.grid(row=0, column=1)

  17.         tk.Label(self.root, text="映射键:").grid(row=1, column=0)
  18.         self.map_key_entry = tk.Entry(self.root)
  19.         self.map_key_entry.grid(row=1, column=1)

  20.         # 创建按钮
  21.         tk.Button(self.root, text="开始运行", command=self.start_mapping).grid(row=2, column=0)
  22.         tk.Button(self.root, text="退出", command=self.stop_mapping).grid(row=2, column=1)

  23.     def start_mapping(self):
  24.         self.listen_key = self.listen_key_entry.get()
  25.         self.map_key = self.map_key_entry.get()

  26.         # 启动键盘监听
  27.         self.listener = Listener(on_press=self.on_press)
  28.         self.listener.start()
  29.         print('开始监听了')

  30.     def stop_mapping(self):
  31.         if self.listener:
  32.             self.listener.stop()
  33.         self.root.quit()

  34.     def on_press(self, key):
  35.         if hasattr(key, 'char') and key.char == self.listen_key:
  36.             print(self.listen_key)
  37.             self.keyboard.press(Key.backspace)
  38.             self.keyboard.release(Key.backspace)
  39.             self.keyboard.type(self.map_key)
  40.             self.keyboard.release(self.map_key)  # 添加释放映射键的操作

  41. if __name__ == "__main__":
  42.     root = tk.Tk()
  43.     app = KeyMapperApp(root)
  44.     root.mainloop()
复制代码


希望这能解决你的问题!如果还有其他疑问,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-4-23 21:21:10 | 显示全部楼层
FishC 发表于 2024-4-23 21:18
你的代码基本上是正确的,只是在键盘精灵的逻辑上有一点小问题。当监听到按下的键是你设定的监听键时,你用 ...

运行后,按A,没反应,实际没有实时监听键盘的按键
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-4-23 21:21:34 | 显示全部楼层
rsj0315 发表于 2024-04-23 21:21
运行后,按A,没反应,实际没有实时监听键盘的按键


抱歉,有时候在使用pynput库时监听按键可能会遇到问题。我们可以尝试使用Python的另一个库来实时监听键盘按键,那就是`pyautogui`库。下面是改进后的代码:

  1. import tkinter as tk
  2. import pyautogui

  3. class KeyMapperApp:
  4.     def __init__(self, root):
  5.         self.root = root
  6.         self.root.title("键盘映射器")

  7.         # 设置UI界面
  8.         self.setup_ui()

  9.         # 初始化监听状态
  10.         self.is_listening = False

  11.     def setup_ui(self):
  12.         # 创建标签和输入框
  13.         tk.Label(self.root, text="监听键:").grid(row=0, column=0)
  14.         self.listen_key_entry = tk.Entry(self.root)
  15.         self.listen_key_entry.grid(row=0, column=1)

  16.         tk.Label(self.root, text="映射键:").grid(row=1, column=0)
  17.         self.map_key_entry = tk.Entry(self.root)
  18.         self.map_key_entry.grid(row=1, column=1)

  19.         # 创建按钮
  20.         tk.Button(self.root, text="开始运行", command=self.start_mapping).grid(row=2, column=0)
  21.         tk.Button(self.root, text="退出", command=self.stop_mapping).grid(row=2, column=1)

  22.     def start_mapping(self):
  23.         if self.is_listening:
  24.             return

  25.         self.listen_key = self.listen_key_entry.get()
  26.         self.map_key = self.map_key_entry.get()

  27.         # 开始监听
  28.         self.is_listening = True
  29.         while self.is_listening:
  30.             if pyautogui.keyIsDown(self.listen_key):
  31.                 self.process_mapping()
  32.                 break

  33.     def stop_mapping(self):
  34.         self.is_listening = False
  35.         self.root.quit()

  36.     def process_mapping(self):
  37.         pyautogui.press(self.map_key)

  38. if __name__ == "__main__":
  39.     root = tk.Tk()
  40.     app = KeyMapperApp(root)
  41.     root.mainloop()
复制代码


这里改用了`pyautogui`库中的`keyIsDown`函数来判断是否按下了监听键,如果按下则进行映射操作。监听部分的逻辑改为使用循环,实现近实时的监听。按下开始按钮后,只有在监听状态下敲击了监听键才会触发映射操作。

希望这次能解决你的问题!如果还有其他疑问,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-4-23 21:28:22 | 显示全部楼层
  1. import tkinter as tk
  2. from pynput.keyboard import Controller, Listener, Key

  3. class KeyMapperApp:
  4.     def __init__(self, root):
  5.         self.root = root
  6.         self.root.title("键盘映射器")

  7.         self.setup_ui()
  8.         self.keyboard = Controller()
  9.         self.listener = None

  10.     def setup_ui(self):
  11.         tk.Label(self.root, text="监听键:").grid(row=0, column=0)
  12.         self.listen_key_entry = tk.Entry(self.root)
  13.         self.listen_key_entry.grid(row=0, column=1)

  14.         tk.Label(self.root, text="映射键:").grid(row=1, column=0)
  15.         self.map_key_entry = tk.Entry(self.root)
  16.         self.map_key_entry.grid(row=1, column=1)

  17.         tk.Button(self.root, text="开始运行", command=self.start_mapping).grid(row=2, column=0)
  18.         tk.Button(self.root, text="退出", command=self.stop_mapping).grid(row=2, column=1)

  19.     def start_mapping(self):
  20.         self.listen_key = self.listen_key_entry.get().lower()  # 强制转换为小写
  21.         self.map_key = self.map_key_entry.get().lower()  # 强制转换为小写
  22.         # print(f"监听键:{self.listen_key}, 映射键:{self.map_key}")

  23.         # 启动键盘监听
  24.         self.listener = Listener(on_press=self.on_press, daemon=True)
  25.         self.listener.start()

  26.     def stop_mapping(self):
  27.         if self.listener:
  28.             self.listener.stop()
  29.         self.root.quit()

  30.     def on_press(self, key):
  31.         try:
  32.             key_char = key.char if hasattr(key, 'char') else ''
  33.             # print(f"按下了:{key_char}")
  34.             if key_char == self.listen_key:
  35.                 self.keyboard.press(Key.backspace)
  36.                 self.keyboard.release(Key.backspace)
  37.                 self. keyboard.type(self.map_key)
  38.                 self.keyboard.press(Key.tab)
  39.                 self.keyboard.release(Key.tab)
  40.                 # return False
  41.         except Exception as e:
  42.             print(f"Error: {e}")

  43. if __name__ == "__main__":
  44.     root = tk.Tk()
  45.     app = KeyMapperApp(root)
  46.     root.mainloop()
复制代码

这个实现了我要的效果
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-4-23 21:28:40 | 显示全部楼层
rsj0315 发表于 2024-04-23 21:28
import tkinter as tk
from pynput.keyboard import  ...


很高兴听到这个代码实现了你想要的效果!这是一个非常简洁和有效的键盘精灵应用程序。

在你的代码中,你增加了Try-Except语句来捕获异常,这是一个很好的做法,可以使程序更加健壮。此外,在监听键和映射键的获取上,你将它们都转换为小写字母,这是一个很好的处理方式,以确保不会因为大小写问题而导致监听失效。

总的来说,你的代码看起来非常棒!如果你还有其他问题或需要进一步的帮助,请随时提问。继续努力学习编程!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-4-24 11:06:42 | 显示全部楼层    本楼为最佳答案   
我试了你的代码没有问题呀
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-4-24 13:51:19 | 显示全部楼层
isdkz 发表于 2024-4-24 11:06
我试了你的代码没有问题呀

是的,最后这次这个好使。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-4-24 16:33:08 | 显示全部楼层
我知道游戏中的改键精灵
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-4 09:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表