pyautowin笔记
Application(backend='uia').start(cmd_line=r"xxx.exe", work_dir=r"xxxApplication") # backend优先使用'uia';拿不到元素,在考虑换'win32'
app = Application(backend='uia').connect(path="xxx.exe") # 连接exe进程名称
win = app.window(title_re="CLIP.*") # 主窗
win.print_control_identifiers()
win_err = app.window(title_re="Error") # 弹窗及其子元素需要额外获取
====》 判断程序的backend
法1:使用工具spy++
如果是GUI的程序,用spy++这个微软的小工具来看,从类名前缀能看出是什么编写的程序。
a、afx__开头的:mfc写的;
b、t_开头的:一般是delphi,少部分是c++builder;比如主窗体一般是tMainForm;
c、thunder_开头的:一般是VB6写的;
d、windows__开发头的,一般都是.net写的;
e、awt__或者swing__开头的,一般都是java写的;
f、其他的直接以win32api gui控件开头的,一般都是c++或者VC++写的。
法2:使用工具inspect
点击inspect左上角的下拉列表,切换到“UI Automation”,然后鼠标点一下你需要测试的程序窗体,inspect就会显示相关信息。
inspect中显示了程序的有关信息,说明backend为uia,inspect中显示拒绝访问,说明程序的backend应该是win32
=================================
===》 特殊元素识别【无text,只有uname,靠下标获取元素】
def capture_as_image(self, rect=None): # 转自 https://www.cnblogs.com/qican/p/13262198.html """ Return a PIL image of the control. See PIL documentation to know what you can do with the resulting image. """ control_rectangle = self.rectangle() if not (control_rectangle.width() and control_rectangle.height()): return None # PIL is optional so check first if not ImageGrab: print("PIL does not seem to be installed. " "PIL is required for capture_as_image") self.actions.log("PIL does not seem to be installed. " "PIL is required for capture_as_image") return None if rect: control_rectangle = rect # get the control rectangle in a way that PIL likes it width = control_rectangle.width() height = control_rectangle.height() left = control_rectangle.left right = control_rectangle.right top = control_rectangle.top bottom = control_rectangle.bottom box = (left, top, right, bottom) # check the number of monitors connected if (sys.platform == 'win32') and (len(win32api.EnumDisplayMonitors()) > 1): hwin = win32gui.GetDesktopWindow() hwidef capture_as_image(self, rect=None): """ Return a PIL image of the control. See PIL documentation to know what you can do with the resulting image. """ control_rectangle = self.rectangle() if not (control_rectangle.width() and control_rectangle.height()): return None # PIL is optional so check first if not ImageGrab: print("PIL does not seem to be installed. " "PIL is required for capture_as_image") self.actions.log("PIL does not seem to be installed. " "PIL is required for capture_as_image") return None if rect: control_rectangle = rect # get the control rectangle in a way that PIL likes it width = control_rectangle.width() height = control_rectangle.height() left = control_rectangle.left right = control_rectangle.right top = control_rectangle.top bottom = control_rectangle.bottom box = (left, top, right, bottom)
pyautogui.screenshot(imageFilename=img_path, , region=(left, top, width, height))
'''
# check the number of monitors connected if (sys.platform == 'win32') and (len(win32api.EnumDisplayMonitors()) > 1): hwin = win32gui.GetDesktopWindow() hwindc = win32gui.GetWindowDC(hwin) srcdc = win32ui.CreateDCFromHandle(hwindc) memdc = srcdc.CreateCompatibleDC() bmp = win32ui.CreateBitmap() bmp.CreateCompatibleBitmap(srcdc, width, height) memdc.SelectObject(bmp) memdc.BitBlt((0, 0), (width, height), srcdc, (left, top), win32con.SRCCOPY) bmpinfo = bmp.GetInfo() bmpstr = bmp.GetBitmapBits(True) pil_img_obj = Image.frombuffer('RGB', (bmpinfo['bmWidth'], bmpinfo['bmHeight']), bmpstr, 'raw', 'BGRX', 0, 1) else: # grab the image and get raw data as a string pil_img_obj = ImageGrab.grab(box) return pil_img_obj ndc = win32gui.GetWindowDC(hwin) srcdc = win32ui.CreateDCFromHandle(hwindc) memdc = srcdc.CreateCompatibleDC() bmp = win32ui.CreateBitmap() bmp.CreateCompatibleBitmap(srcdc, width, height) memdc.SelectObject(bmp) memdc.BitBlt((0, 0), (width, height), srcdc, (left, top), win32con.SRCCOPY) bmpinfo = bmp.GetInfo() bmpstr = bmp.GetBitmapBits(True) pil_img_obj = Image.frombuffer('RGB', (bmpinfo['bmWidth'], bmpinfo['bmHeight']), bmpstr, 'raw', 'BGRX', 0, 1) else: # grab the image and get raw data as a string pil_img_obj = ImageGrab.grab(box) return pil_img_obj'''
1)截取该元素
2)图片识别位置、文本【若有】、颜色识别
3)点击识别的文字
===================
1、有名称,可以直接用 win[name]的方式获取,即 win.print_control_identifiers() 可以打印出来名称的。
2、大多数元素用click_input()即可,不行,尝试用click();【部分元素虽然是表面是wrapper,但实际是btn和checkbox,可以用click()]
3、无名称的元素,可以用父元素的descendents()获取,如dlag_win.descendants(),得到一个list,用index取元素,进行点击
4、元素查看用 inspect.exe; 下载安装windows sdk里面自带:https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk/#sysreq
5、窗口选择
1)、根据窗口标题/类名选择: app["QQ"]
2)根据窗口类名选择 :window = app.TXGuiFoundation
3)获取坐标 : print(app["QQ"].rectangle())
6 窗口控件基本属性获取方法
1)获取控件类型:wrapper_object()
2)获取控件支持的方法:print(dir(a.wrapper_object()))
3) 获取控件的子元素:children()
4)获取控件类名:class_name()
5)以字典的形式返回控件的属性:get_properties()
【以上全部可以用inspect直接查看获取】
7。文本 ele.texts()
8 控件/窗口截图:
ele.capture_as_image()`
9 菜单操作:
# 通过下标选择菜单项
menu = window['menu'] print(menu.items())#获取菜单的子菜单项 m = menu.item_by_index(1) print(m)
# 通过路径选择菜单项
menu = window['menu']
print(menu.items())#获取菜单的子菜单项
m = menu.item_by_path("文件->新建连接...")
print(m)
10 等待:window.wait(wait_for='ready',timeout=10,retry_inteval=1)
官网: https://pywinauto.readthedocs.io/en/latest/code/pywinauto.application.html?highlight=wait#pywinauto.application.WindowSpecification.wait
参考:https://www.pythonf.cn/read/127079#timings_161
参考:https://www.cnblogs.com/wuxunyan/p/9366178.html