
実現したいこと
Pythonでプログラムによるキーの押し下げを無視して物理的な押し下げを検出する方法を知りたいです
前提
プログラムによる押し下げとは左クリックで言いますと
pyautogui.mouseDown(button='left')
pyautogui.mouseUp(button='left')
といったものです。
物理的な押し下げは実際にマウスで左クリックしたときです。
これをwindowsのapictypes.windll.user32.GetAsyncKeyState(0x01) & 0x8000等では判別できず、を利用している?AutoHotKeyのGetKeyState(#InstallMouseHook使用)ではできることなのでいまいち腑に落ちないのです。
おそらくそれ
(https://ahkwiki.net/GetKeyState)
一応、判別自体はahk Python wrapper(https://ahk.readthedocs.io/en/latest/)を使用することによって解決しているといえばしています。
下記を動かしてもらえばどのようなことかわかると思います。(AutoHotKeyのインストールが必須です)
発生している問題・エラーメッセージ
エラーメッセージ エラー等は出ません ### 該当のソースコード import tkinter as tk import ctypes import threading import pyautogui import time from pynput import mouse, keyboard from ahk import AHK from ahk.directives import InstallMouseHook class Application(tk.Frame): def __init__(self, master=None): super().__init__(master) self.master = master self.master.attributes("-topmost", True) self.my_title = "test" self.back_color = "#FFFFFF" self.master.title(self.my_title) self.master.geometry("300x200") self.create_widgets() self.pack() self.virtual_left_click=False self.virtual_left_click_thread=None self.keyboard_listener = keyboard.Listener(on_press=self.on_key_press) self.keyboard_listener.name = "KeyboardListenerThread" self.keyboard_listener.start() self.mouse_listener = mouse.Listener(on_click=self.on_mouse_click) self.mouse_listener.name = "MouseListenerThread" self.mouse_listener.start() self.ahk = AHK(executable_path="AutoHotKeyのパス", directives=[InstallMouseHook]) def create_widgets(self): self.desc1 = tk.Label(self, text='F3キーを押すことで左クリックがホールドされます') self.desc1.pack(pady=10) self.desc2 = tk.Label(self, text='物理ボタン:') self.desc2.pack() self.physical_left_click_label = tk.Label(self, text='左クリックは押されてません') self.physical_left_click_label.config(bg="gray", fg="white") self.physical_left_click_label.pack(pady=10) self.desc3 = tk.Label(self, text='物理ボタンおよびプログラムによる押下:') self.desc3.pack() self.virtual_left_click_label = tk.Label(self, text='左クリックは押されてません') self.virtual_left_click_label.config(bg="gray", fg="white") self.virtual_left_click_label.pack(pady=10) def on_key_press(self, key): if key == keyboard.Key.f3: self.toggle_left_click() def on_mouse_click(self, x, y, button, pressed): if button == mouse.Button.left: if pressed: self.virtual_left_click_label.config(text='左クリック押下中...', bg="red") if self.ahk.key_state("LButton",mode ="P") == 1: #AHKのGetKeyStateのmode ="P"はソフトウェア的なキーボードイベント生成を無視し、 #実際にユーザーがキーを押しているかを取得できる。 self.physical_left_click_label.config(text='左クリック押下中...', bg="red") else: self.virtual_left_click_label.config(text='左クリックは押されてません', bg="gray") if self.ahk.key_state("LButton",mode ="P") == 0: self.physical_left_click_label.config(text='左クリックは押されてません', bg="gray") def toggle_left_click(self): if self.virtual_left_click_thread is None: self.virtual_left_click_thread = threading.Thread(target=self.left_click_func, name="HoldLeftClickThread") if not self.virtual_left_click: self.virtual_left_click= True self.virtual_left_click_label.config(text='左クリック押下中...', bg="red") if self.virtual_left_click_thread.is_alive(): self.virtual_left_click_thread.join() self.virtual_left_click_thread = threading.Thread(target=self.left_click_func, name="HoldLeftClickThread") self.virtual_left_click_thread.start() else: self.virtual_left_click_label.config(text='左クリックは押されてません', bg="gray") self.virtual_left_click = False def left_click_func(self): while self.virtual_left_click: pyautogui.mouseDown(button='left') time.sleep(0.0001) pyautogui.mouseUp(button='left') if __name__ == "__main__": root = tk.Tk() app = Application(master=root) app.mainloop() ### 試したこと pyautoguiではなく、ctypes.windll.user32.SendInputでマウスを動かしたりしました。 ### 補足情報(FW/ツールのバージョンなど) Windows 10 Python 3.10.8 AutoHotKey 3.10.8


回答2件
あなたの回答
tips
プレビュー