我编写了一个简单的程序,它允许您记录点击事件并保存它们。然后您可以再次加载保存,它会在您保存它们时再次触发所有点击事件。对于想知道的人,我在一年前编写了这个程序用于学习目的。那时它工作得很好。我今天想再次使用它,但它不再正常运行。
我启动程序,然后选择调用 selectAndSavePoints 方法的选项 1。它等到我按下 s 键开始,然后继续监视点击事件。问题是,它阻止了它们。我可以看到单击事件的位置写在控制台中,但是当我例如单击任务栏中的资源管理器图标以将其打开时,它不会打开,因为单击事件被劫持而不是被监视并允许通过 Windows 操作系统。
我尝试通过在 loadAndExecutePoints 方法中复制我的 click 方法并将其放置在全局 coordsToClick 变量声明上方的 MonitorMouseClicks 方法中来解决此问题。然后我会在 onclick 方法中调用 click 方法以再次手动单击它。当我运行它时,它会注册第一次单击,我可以看到它再次记录,然后程序应该为我手动单击它,但是该过程随后挂起。然后按 alt + f4、ctrl + break 或 taskkilling 程序不起作用。我必须重新启动计算机才能使命令行窗口消失。我不知道这里发生了什么。
from keyboard import wait
from threading import Thread
from pythoncom import PumpMessages
from ctypes import windll
from pyHook import HookManager
from os import listdir
from win32api import mouse_event
from win32api import SetCursorPos
from win32con import MOUSEEVENTF_LEFTDOWN
from win32con import MOUSEEVENTF_LEFTUP
from time import sleep
coordsToClick = []
def sanitised_input(prompt, type_=None, min_=None, max_=None, range_=None, distinct_=False):
if min_ is not None and max_ is not None and max_ < min_:
raise ValueError("min_ must be less than or equal to max_.")
while True:
ui = input(prompt)
if type_ is not None:
try:
ui = type_(ui)
except ValueError:
print("Input type must be {0}.".format(type_.__name__))
continue
if max_ is not None and ui > max_:
print("Input must be less than or equal to {0}.".format(max_))
elif min_ is not None and ui < min_:
print("Input must be greater than or equal to {0}.".format(min_))
elif range_ is not None and ui not in range_:
if isinstance(range_, range):
print("Input must be between {0.start} and {0.stop}.".format(range_))
else:
if len(range_) == 1:
print("Input must be {0}.".format(*range_))
else:
print("Input must be {0}.".format(" or ".join((", ".join(map(str, range_[:-1])), str(range_[-1])))))
elif distinct_ and not len(ui) == len(set(ui)):
print("Input should only contain unique characters!")
else:
return ui
def selectAndSavePoints():
print("Press the key 's' to start selecting points")
print("Press the key 'p' to cancel last selected point, so previous action is undone. Does work multiple times")
print("Once you're finished, press the key 'f' to save them")
wait("s")
def MonitorKeyPresses(_hookManager):
global coordsToClick
def onpress(event):
if event.Key == "P":
del coordsToClick[-1]
return 0
_hookManager.SubscribeKeyDown(onpress)
_hookManager.HookKeyboard()
PumpMessages()
def MonitorMouseClicks(_hookManager):
global coordsToClick
def onclick(event):
coordsToClick.append(event.Position)
print(event.Position)
return 0
_hookManager.SubscribeMouseLeftDown(onclick)
_hookManager.HookMouse()
PumpMessages()
hookManager = HookManager()
threadClick = Thread(target = MonitorMouseClicks, args = (hookManager,))
threadClick.start()
threadPress = Thread(target = MonitorKeyPresses, args = (hookManager,))
threadPress.start()
wait('f')
windll.user32.PostQuitMessage(0)
hookManager.UnhookMouse()
hookManager.UnhookKeyboard()
filename = input("Enter the filename: ")
file = open("../Saves/" + filename + ".txt", 'w')
for coords in coordsToClick:
file.write(str(coords[0]) + ":" + str(coords[1]) + "\n")
file.close()
def loadAndExecutePoints():
def click(x, y):
SetCursorPos((x, y))
mouse_event(MOUSEEVENTF_LEFTDOWN,x,y,0,0)
mouse_event(MOUSEEVENTF_LEFTUP,x,y,0,0)
files = listdir("../Saves")
for i in range(len(files)):
print("[" + str(i) + "]: " + files[i])
filenumber = sanitised_input("Enter the file mumber: ", type_=int, range_=range(len(files)))
filename = files[filenumber]
print("Press 's' to start executing the clicks")
wait('s')
lines = [line.rstrip('\n') for line in open('../Saves/' + filename)]
for line in lines:
components = line.split(":")
click(int(components[0]), int(components[1]))
sleep(0.2)
def main():
print("Select a option")
print("[1]: Select and Save Points")
print("[2]: Load and Execute Points")
option = sanitised_input("", type_=int, range_=(1, 2))
if(option == 1):
selectAndSavePoints()
else:
loadAndExecutePoints()
while(True):
main()
我希望能够在这里找到可以帮助我弄清楚此应用程序停止工作的原因,确切的问题是什么以及如何解决或修复它的人。正如你在程序中看到的,我使用了很多导入。它们中的大多数是默认模块,但这里是获取非默认模块的说明。
pip install keyboard
pip install pywin32
pyHook 模块可以在这里下载https://www.lfd.uci.edu/~gohlke/pythonlibs/#pyhook。我下载了 pyHook‑1.5.1‑cp35‑cp35m‑win_amd64.whl 文件,然后您可以使用此命令进行安装
pip install pyHook‑1.5.1‑cp35‑cp35m‑win_amd64.whl
顺便说一句,我正在使用 python 3.5.4。