目录
前言:
在用Python制作办公软件或游戏等自动化脚本的时候,往往需要查找软件的句柄以及控件的信息,以实现类似于按键精灵的自动化功能。为了方便这一步操作,我制作了一个UI操作界面。
然后关于使用的库为pywinauto,本库可以实现大部分自动化脚本操作的功能。
使用说明:
按下句柄查找操作后,控制台会打印出相关信息,类似如下:
就以我制作的这个UI操作软件为例,简单说明一下自动化脚本的实现:
数字部分就是句柄信息,数字前的所有内容即为标题信息。即
句柄:“2364290” 、对应的标题:“句柄与控件查找”。
在输入栏里面粘贴进标题后,按下控件查找就能查到相关控件的信息了。如下:
通过控件信息就能直接利用脚本操作按键了
代码如下:
from tkinter import *#库自带
import win32gui #pip install pywin32
from pywinauto import application#pip install pywinauto
class command:
def __init__(self):
self.hwnd_title = dict()
def get_all_hwnd(self,hwnd,mouse):
if win32gui.IsWindow(hwnd) and win32gui.IsWindowEnabled(hwnd) and win32gui.IsWindowVisible(hwnd):
self.hwnd_title.update({hwnd:win32gui.GetWindowText(hwnd)})
def handle_find(self):#查找句柄
win32gui.EnumWindows(self.get_all_hwnd, 0)
for h,t in self.hwnd_title.items():
if t is not "":
print(t,h)#其中t为标题,h为句柄数值
def control_find(self):#查找控件信息
title=self.lo.get()
app=application.Application().connect(title_re=title)
window_title=[title]
app[window_title].print_control_identifiers(filename="C:\\L\\1.txt")
class main(command):
def interface(self):
root = Tk()
root.title("句柄与控件查找")
root.geometry("400x250")
root.resizable(width=False, height=False)
fm1=Frame(root)
Button(fm1,text='句柄查找',font=('Arial', 12),command=self.handle_find,activeforeground="white",activebackground='gray',bg='white',fg='black',width=10,wraplength=100).pack(side=LEFT,padx=10)
self.lo=Entry(fm1, show=None, font=('Arial', 14),width=15)
self.lo.insert(0, '请输入标题')
self.lo.pack(side=LEFT,padx=10)
fm1.pack(side=TOP,pady=30)
fm1=Frame(root)
Button(fm1,text='控件查找',font=('Arial', 12),command=self.control_find,activeforeground="white",activebackground='gray',bg='white',fg='black',width=10,wraplength=100).pack(side=LEFT,padx=10)
Label(fm1, text=" ", bd=1, font=("Arial",12), width=20, height=1).pack(side=LEFT)
fm1.pack(side=TOP)
root.mainloop()
if __name__ == '__main__':
main().interface()
补充(重要更改):
关于pywinauto库控件信息打印的问题。针对大型的控件超多的软件,比如excel,word等这些,原库中的打印函数print_control_identifiers()是只打印在控制台页面上,控件信息一多,前面的信息就会被后面的覆盖,所以会遗漏掉很多重要控件的信息,以至于后续无法继续操作。
而针对这个问题,我们不得不要把这些控件信息一一不漏的保存在其他文档里面,比如txt文件中。因此需要对原函数print_control_identifiers()的内容进行部分修改。
步骤如下:
1.首先建立一个txt文件,路径自定义。
2.找到原函数print_control_identifiers()如下:
在注释行后添加读取txt文件的函数:
f2= open("C:\\L\\1.txt","w",encoding='utf-8')
3.找到这行函数:
在变量output后加入写入txt的函数
f2.write(output)
3.最后在函数print_control_identifiers()末尾增加关闭函数,保存
f2.close()
大致如下:
以上,操作完成
pywinauto控件操作总结:
以下是根据自己实践过程中遇到的一些常用控件的操作方法(持续更新)
前置代码:
from pywinauto import application
title="这里输入你的句柄标题"
#连接软件的方式:
#方式1:
app=application.Application().connect(title_re=title)
#方式2:
app=application.Application().connect(handle=123456)#输入句柄
window_title=[title]
Button
控件信息类似如下:
控制需求——单击/双击:
#方式1:
app[window_title].child_window(title="开始",found_index=0).click()
#在控件信息中如果有多个相同title时,防止程序可能的保存,可采用found_index,如果确定只有唯一一处时,可省略改参数
#方式2:
app[window_title].Button46.click()
#双击:
app[window_title].Button46.double_click()
Edit
控件信息类似如下:
控制需求——输入文字:
关键字:set_edit_text()
app[window_title].Edit2.set_edit_text("输入文字")
Menu
控制需求——点击菜单栏里面具体项目:
app[window_title].menu_select("File->open")
ListView
控件信息类似如下:
控制需求——选中列表中的元素:
比如选中第一个元素[wenzi],关键字:get_item(0)
app[window_title].child_window(title="Object list", found_index=0).ListView.get_item(0).click()
报错问题解决
出现以上报错时,是系统权限没打开
from __future__ import print_function
import ctypes, sys
quanxian=0
def is_admin():
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
if is_admin():
quanxian=1
#在这里添加并执行你的代码
else:
if sys.version_info[0] == 3:
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, __file__, None, 1)
else:#在python2.x下执行,python3.x中需要删除
ctypes.windll.shell32.ShellExecuteW(None, u"runas", unicode(sys.executable), unicode(__file__), None, 1)