我想用Python编写一个用于Windows的程序,它将作为一个点击器,其中根据一个键,用户在屏幕上已知的位置按下一个点击。 这用于从网页中的列表中自动select选项。 我有点击部分工作,但我希望能够在执行过程中做出几个点击,就好像有一个接一个的多个列表的测验。
一个select是使用msvcrt
getch()
进行while循环。 事情是在cmd之外单击之后,不再select窗口,而是select目标点所在的窗口。 因此,脚本停止活动,用户不能select其他位置。 解决方法是单击cmd窗口将焦点返回给它,并能够进行更多的点击操作。 为了解决这个问题,有必要创build一个服务,或者根据@Sanju的说法。
另一种select是使用PyHook等键盘logging程序,这似乎是要走的路。 但问题是,我想要使用它的窗口,Flash或另一个animation引擎中的网页会导致一些用户在使用该键盘logging器时发现的错误,例如在Skype中, 这里将对其进行描述。 在我的情况下,这也发生在这个网页上,或者当在窗口本身上进行点击,或者在select了窗口的情况下按下了键。
我的基本代码如下所示,其中click(...)
通常包含坐标作为参数,但为简单起见,它们被省略。 在这种情况下,0结束程序,并有三个选项与数字1-3select。
import msvcrt, win32api, win32con def click(x,y): win32api.SetCursorPos((x,y)) win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,x,y,0,0) win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,x,y,0,0) key=0 while key!=b'0': key=msvcrt.getch() if key==b'1': click(...) elif key==b'2': click(...) elif key==b'3': click(...)
下面的尝试是实现@三's的build议,首先是整个线程内部,然后是queue
,两者都不像预期的那样工作。
import threading, msvcrt, win32api, win32con def MyThread(): key=0 while key!=b'0': key=msvcrt.getch() if key==b'1': ... def click(x,y): ... threading.Thread(target=MyThread,args=[]).start()
。
import queue, threading, msvcrt, win32api, win32con def MyThread(key): while key.get()!=b'0': key.put(msvcrt.getch()) if key.get()==b'1': ... def click(x,y): ... key=queue.Queue() key.put(0) threading.Thread(target=MyThread,args=[key]).start()
另一个尝试使用PyHook,但它仍然面临着上述问题。
import pyHook, pythoncom, win32api, win32con def OnKeyboardEvent(event): if event.Key=='Numpad1': ... def click(x,y): ... hm=pyHook.HookManager() hm.KeyDown=OnKeyboardEvent hm.HookKeyboard() pythoncom.PumpMessages()
所有你需要的是将你的点击部分移动到一个线程,并使用诸如队列之类的可分享对象来共享用户输入。 这听起来像是一个矫枉过正的事情,但这是让你的任务保持在后台的方法。
顺便说一句,你有许多Python的GUI应用程序框架可用,如tkinter,wxpython,可以缓解你的目标。