多窗口下的批量操作脚本 - 利用win32gui和WindowSpy++简单实现目标窗口前置
使用的模块:pyautogui, win32gui
使用的工具:windowspy++
背景:最近要用帮同学处理400+张图片的文字识别,考虑用python实现 [天若ocr] 的批处理,临时抱佛脚学了一些东西,过程磕磕绊绊的,就记录一下。
1. 鼠标键盘动作模拟的模块(包)选择
百度到的键鼠模拟包主要有pyuserinput和pyautogui两个包可选,具体如下:
pyuserinput: 集成了py3.x之前的pymouse和pykeyboard等模块,需要先安装pyhook环境,之后可以pip install pyuserinput
pyautogui: windows下可直接pip install pyautogui
两者都可以实现丰富的键鼠操作,但我在尝试userinput的时候遇到了一些问题:不同系统的键盘名称有区别,但不太好找到windows对应的键盘名称表。
多次尝试无果后,我就选择了pyautogui,它功能与userinput无异、可以直接使用pip安装,还能很方便地找到一些函数和按键的快查表(如 https://blog.csdn.net/ibiao/article/details/77859997 - "pyautogui (一)")。
* 在使用pyautogui的过程中,我遇到了一些问题,如反复使用pyautogui.hotkey('ctrl','v')来模拟ctrl+v热键的时候,有一定的概率出错。我的解决方式是十分笨拙的手动模拟:
1 import pyautogui as pg 2 3 pg.keydown('ctrl') 4 pg.press('v') 5 pg.keyup('ctrl')
2.多窗口下切换前置窗口
本着少做调查研究的原则,我本来是打算用模拟键盘alt+tab的方法直接实现切换窗口的,甚至计算了多个窗口下置换前置的排列组合方法。但是……天若ocr是一个联网才能使用的工具,在 [识别 - 跳出结果窗口] 的时间里,窗口的排列顺序是不确定的,所以多次反复的tab下结果总是不稳定……于是最终还是使用了win32。
论坛里关于使用win32将需要的窗口前置以方便模拟操作的攻略很少,这也是我写这一篇的动机。其实有非常简单的实现方法:
①确认需要前置的窗体信息:
告诉win32前置窗体之前,我们需要得到这个窗体的信息。各种论坛中获取窗体信息的方法主要有使用win32的代码、使用windowsspy++、使用按键精灵等。尝试后我觉得windowsspy++是最好入门的。这是一款安装和使用的傻瓜机器,点击窗体就能直接看到窗体句柄(窗体的id)、窗体标题、窗体类名等等信息。窗体句柄和标题(比如图片查看器)是经常会变动的,网友们有各种各样的方法来实时获取窗体句柄,而这里我…………为了偷懒,在窗体关系并不复杂的前提下,我选择了用窗体类名而不是句柄或窗体标题来直接区别不同窗体。
如批量ocr过程中需要前置操作的窗口有[图片查看器]和[文本编辑器],通过windowsspy++我得到:记事本的窗体类名是notepad,而windows照片查看器的窗体类名是photo_lightweight_viewer。
②使用win32前置窗体:
如定义函数,前置[图片查看器]的代码如下:
1 import win32gui 2 3 def fore_text(): 4 #描述类名 5 cla = 'notepad' 6 #利用方法,通过类名找到窗体句柄 7 ctjb = win32gui.findwindow(cla,none) 8 #利用方法,通过窗体句柄前置窗体 9 win32gui.setforegroundwindow(ctjb)
* win32gui.findwindow()函数的信息如下:
(转载自https://blog.csdn.net/guangyinglanshan/article/details/77847952,"如何利用python和win32编程避免重复性体力劳动(一)——开始、findwindow和findwindowex")
3.案例的程序实现
虽然折腾了很久,但这个批量应用天若ocr的小脚本最后显得非常简单……具体代码如下:
1 import pyautogui as pg 2 import time 3 import win32gui 4 5 pg.pause = 1.0 6 7 #window ranges 8 def fore_picview(): 9 cla = 'photo_lightweight_viewer' 10 hld = win32gui.findwindow(cla,none) 11 win32gui.setforegroundwindow(hld) 12 13 def fore_text(): 14 cla = 'notepad' 15 hld = win32gui.findwindow(cla,none) 16 win32gui.setforegroundwindow(hld) 17 18 19 ## make sure tianruo is open 20 21 ########### 22 fore_picview() 23 24 for i in range(0,100): 25 26 27 #f4 28 pg.press('f4') 29 30 #choose rec 31 pg.click(650,400) 32 time.sleep(2.0) 33 34 #change window 35 fore_text() 36 37 38 #ctrl_v 39 pg.keydown('ctrl') 40 pg.press('v') 41 pg.keyup('ctrl') 42 pg.press('enter') 43 pg.press('enter') 44 45 #change window 46 fore_picview() 47 48 pg.press('right')
上一篇: Kotlin介绍(非原创)
下一篇: 类的property特性