用Python点击工具栏按钮实例

Python笔记 无标签 2020-03-10 阅读:248

前言

我实习工作岗位是软件测试,去年年底的时候,小组内计划弄个自动化测试方案,方案是组长来策划,代码编写部分由我来负责(我只是个测试,不太懂代码,只是比其他成员会的多一点)。

关于这个自动化方案,需要控制电脑上正在运行的程序——”BSSim“,我选择用Python来实现这个功能,

第一步:获取(BSSim)程序的主窗体句柄

目的:得到BSSim程序的主窗体句柄(mainHandle)

已知:BSSim程序名为“Base Station Simulator”,也就是BSSim程序的标题为“Base Station Simulator”

实现思路:

  1. Python获取电脑上正在运行的所有程序的标题(Title)和句柄(Handle),存储到一个字典中
  2. 从字典中查找包含BSSim标题的值所对应的键(key),得到的键,就是BSSim的主窗体句柄(mainHandle)

代码如下:

mainFormList = dict() # 存储程序标题(Title)和句柄(Handle)的字典

def get_all_hwnd(hwnd,mouse):
    if win32gui.IsWindow(hwnd) and win32gui.IsWindowEnabled(hwnd) and win32gui.IsWindowVisible(hwnd): # 不显示所有程序
        mainFormList.update({hwnd:win32gui.GetWindowText(hwnd)}) # 更新mainFormList
win32gui.EnumWindows(get_all_hwnd, 0)

#从 mainFormList 字典中查询值包含'Base Station Simulator'的键
keys = [x[0] for x in mainFormList.items() if 'Base Station Simulator' in x[1]]
# 取出keys的数据
for i in keys: 
    mainHandle = i # 得到BSSim的主窗体句柄

第二步:获取子窗体(ToolbarWindow32)的句柄

目的:因为需要让Python控制的按钮,正是位于BSSim子窗体ToolbarWindow32中

已知:BSSim程序的主窗体句柄(mainHandle)、ToolbarWindow32窗体的标题(Title)

实现思路:

  1. 通过主窗体句柄(mainHandle),列出所有子句柄,并存入列表(childHandleList)中
  2. 获取列表(childHandleList)中所有句柄的标题,并存入列表(childTitleList)中
  3. 将两个列表(childHandleList 和 childTitleLIst)组成键值对,存入字典中 (补充:这一步是为了得到Title时,方便得到对应的Handle,当然也有其他方法,因为这两个列表中的数据是一一对应的)
  4. 从字典中查找包含ToolbarWindow32标题的值所对应的键,得到的键,就是ToolbarWindow32窗体的句柄(toolbarwindow32Handle)

代码如下:

childHandleList = [] # 存储子窗体句柄的列表
childTitleList = [] # 存储子窗体标题的列表

# 通过主窗体句柄,枚举出所有子窗口,并存入childHandleList
win32gui.EnumChildWindows(mainHandle, lambda hwnd, param: param.append(hwnd), childHandleList) 

# 通过句柄得到标题,并存储到 childTitleList
for i in childHandleList:
    childTitleList.append(win32gui.GetClassName(i))

# childHandleList 和 childTitleList 两个list组成字典
childFormList = dict(zip(childHandleList, childTitleList))

# 从 childFormList 列表中查找值为“ToolbarWindow32”的键
keys = [x[0] for x in childFormList.items() if 'ToolbarWindow32' in x[1]]
# 取出keys的数据
for i in keys:
    toolbarwindow32Handle = i # 得到 ToolbarWindow32 的句柄(toolbarwindow32Handle)

第三步:获取ToolbarWindow32窗体的绝对坐标以及其中按钮的坐标

目的:根据ToolbarWindow32窗体的坐标,算出其中按钮的坐标

已知:ToolbarWindow32窗体的句柄(toolbarwindow32Handle)

实现思路:

  1. 将BSSim程序置顶显示 (①避免窗体位于后台,取到的坐标不在屏幕可视范围;②便于后续控制鼠标对窗体进行点击)
  2. 根据ToolbarWindow32的窗体句柄,得出该窗体位于屏幕的坐标
  3. 已知ToolbarWindow32窗体位于屏幕的坐标,算出该窗体中按钮的坐标位置

代码如下:

# 将BSSim窗口置顶——需使用BSSim程序主窗体句柄
win32gui.ShowWindow(mainHandle, win32con.SW_SHOWNORMAL)
win32gui.SetForegroundWindow(mainHandle)

time.sleep(0.5) # 等待窗口置顶 (可省略)

# 得到ToolbarWindow32窗体的屏幕坐标——左上角、右下角,四个值
left, top, right, bottom = win32gui.GetWindowRect(toolbarwindow32Handle)

# 已知ToolbarWindow32窗体位于屏幕的坐标,算出其中按钮的坐标
buttonX = left + ?  # 按钮的 X 轴坐标,'?'可以通过屏幕坐标尺子类似的软件获取
buttonY = top + ?  # 按钮的 Y 轴坐标,'?'可以通过屏幕坐标尺子类似的软件获取

最后:对按钮的屏幕坐标位置执行鼠标点击事件

目的:点击ToolbarWindow32窗体中的按钮,也就是工具栏的按钮

已知:按钮位于屏幕的绝对坐标 buttonX、buttonY

实现思路:

  1. 将鼠标移动到按钮的位置上
  2. 执行鼠标点击事件

代码如下:

# 鼠标移动到按钮的坐标位置
win32api.SetCursorPos((buttonX, buttonY))

# 执行鼠标左键单击
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN | win32con.MOUSEEVENTF_LEFTUP, 0,0,0,0)

结语

关于为什么我要使用获取按钮坐标的方式,对其进行点击操作,为什么不用更简单、更符合自动化的方法?

  1. 因为ToolbarWindow32窗体是工具栏的窗体,只有一个Handle主句柄,其中包含的按钮没有独立句柄
  2. ToolbarWindow32窗体中的按钮,不像菜单中的按钮,拥有菜单ID
  3. 我也不知道ToolbarWindow32窗体中的按钮,是否也拥有类似菜单ID的东西,更不知如何获取
  4. 我查阅了很多资料,实在是没找到其他方法
  5. 以及,我也是初学者,愿意接受大佬指点。

关于Windows窗体程序中我所知道的几种按钮,以及如何用Python向其发送点击消息的相关内容,见我写的另一篇文章——“Python向Windows窗体按钮发送点击消息“。

版权声明

本文基于《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权
文章链接:https://tooler.club/archives/python-click-toolbarwin32-button.html (转载时请注明本文出处及文章链接)

如果觉得我的文章对你有用,请随意赞赏

0条评论