对于常见的窗口程序,需要点点填填的控件有输入框(Edit)、按钮(Button)、复选框(CheckBox)、单选框(RadioButton)、下拉列表(ComboBox).
关于各个控件的函数方法,可以查阅官网 Methods available to each different control type
下面结合程序讲一下各个控件的用法。

要进行文件格式转换,一般需要三步:
1. 选择源文件
2. 转换参数配置
3. 选择输出文件位置
在这里,就是现在文件名后面的编辑框中填入源文件的位置,然后勾选自动扩帧复选框,然后点击转换按钮,最后会弹出一个另存为的文件对话框来选择目标文件位置。
目的明确了,接下来就是如何干的问题了。分两步:
1. 找到控件
2. 操作控件
如何让程序找到控件呢?
最简单的方法就是通过空间特征进行匹配。窗体也可以看成是一个大控件。匹配窗口的方法除了前面提到的window()方法,还可以通过中括号加窗口名。如:
dlg_spec = app.window(title=r'EXE/EXE 转 MP4') # 1
dlg_spec = app[r'EXE/EXE 转 MP4'] # 2
除了title,还可以使用class或者title+class或者相近的text和类来匹配控件。
另外一种方法就是我们知道了这个程序的层次结构,然后类似寻到DOM元素一样一层一层的匹配。
那么如何找到这个层次结构呢。pywinauto提供了print_control_identifiers()函数来显示该窗体下所有控件的结构。
dlg_spec = app[r'EXE/EXE 转 MP4']
dlg_spec.print_control_identifiers()
输出如下:
Control Identifiers:
TEXE2FLVForm - 'EXE/EXE 转 MP4' (L202, T55, R496, B562)
['EXE/EXE 转 MP4TEXE2FLVForm', 'TEXE2FLVForm', 'EXE/EXE 转 MP4']
child_window(title="EXE/EXE 转 MP4", class_name="TEXE2FLVForm")
|
| TTrackBar - '' (L273, T189, R470, B204)
| ['TTrackBar', '下载安装相关视频编码器TTrackBar']
| child_window(class_name="TTrackBar")
|
| TGroupBox - '图像缩小输出时处理方法' (L212, T460, R483, B522)
| ['图像缩小输出时处理方法', 'TGroupBox', '图像缩小输出时处理方法TGroupBox', 'TGroupBox0', 'TGroupBox1']
| child_window(title="图像缩小输出时处理方法", class_name="TGroupBox")
| |
| | RadioButton - '部分画面鼠标自动跟随(动态显示光标附近图像)' (L232, T501, R470, B515)
| | ['RadioButton', '部分画面鼠标自动跟随(动态显示光标附近图像)RadioButton', 'RadioButton1', '部分画面鼠标自动跟随(动态显示光标附近图像)', 'RadioButton0']
| | child_window(title="部分画面鼠标自动跟随(动态显示光标附近图像)", class_name="TRadioButton")
| |
| | RadioButton - '全画面缩放(文字可能会变不清晰)' (L232, T480, R409, B495)
| | ['全画面缩放(文字可能会变不清晰)', 'RadioButton2', '全画面缩放(文字可能会变不清晰)RadioButton']
| | child_window(title="全画面缩放(文字可能会变不清晰)", class_name="TRadioButton")
|
| RadioButton - '部分画面鼠标自动跟随(动态显示光标附近图像)' (L232, T501, R470, B515)
| ['RadioButton', '部分画面鼠标自动跟随(动态显示光标附近图像)RadioButton', 'RadioButton1', '部分画面鼠标自动跟随(动态显示光标附近图像)', 'RadioButton0']
| child_window(title="部分画面鼠标自动跟随(动态显示光标附近图像)", class_name="TRadioButton")
|
| RadioButton - '全画面缩放(文字可能会变不清晰)' (L232, T480, R409, B495)
| ['全画面缩放(文字可能会变不清晰)', 'RadioButton2', '全画面缩放(文字可能会变不清晰)RadioButton']
| child_window(title="全画面缩放(文字可能会变不清晰)", class_name="TRadioButton")
|
| Edit - '扩帧的作用是让鼠标移动更加平滑,文件也会变大一些\r\n如要扩帧建议扩帧后不要超过15帧/秒\r\n' (L225, T298, R477, B319)
| ['自动扩帧Edit0', '自动扩帧Edit', '自动扩帧Edit1', 'Edit', 'Edit1', 'Edit0']
| child_window(title="扩帧的作用是让鼠标移动更加平滑,文件也会变大一些\r\n如要扩帧建议扩帧后不要超过15帧/秒\r\n", class_name="TMemo")
|
| Edit - '除非对FLV的编码器非常熟悉,完全知道自己想要什\r\n么,否则请不要修改默认的编码器设置\r\n' (L214, T115, R483, B143)
| ['Edit2', '浏览Edit']
| child_window(title="除非对FLV的编码器非常熟悉,完全知道自己想要什\r\n么,否则请不要修改默认的编码器设置\r\n", class_name="TMemo")
|
| Button - '转换(&Z)' (L300, T529, R362, B551)
| ['Button', '转换(&Z)', 'Button0', 'Button1', '转换(&Z)Button']
| child_window(title="转换(&Z)", class_name="TButton")
|
| Button - '关闭(&C)' (L370, T529, R432, B551)
| ['关闭(&C)', '关闭(&C)Button', 'Button2']
| child_window(title="关闭(&C)", class_name="TButton")
|
| Button - '浏览' (L434, T88, R483, B106)
| ['Button3', '浏览', '浏览Button']
| child_window(title="浏览", class_name="TButton")
|
| Edit - '' (L259, T88, R429, B107)
| ['EXE/EXE 转 MP4Edit', 'Edit3']
| child_window(class_name="TEdit")
|
| Edit - '5' (L286, T273, R307, B292)
| ['自动扩帧Edit2', 'Edit4']
| child_window(title="5", class_name="TEdit")
|
| CheckBox - '自动扩帧' (L219, T277, R280, B292)
| ['CheckBox1', '自动扩帧', '自动扩帧CheckBox', 'CheckBox', 'CheckBox0']
| child_window(title="自动扩帧", class_name="TCheckBox")
|
| Button - '下载安装相关视频编码器' (L273, T166, R409, B184)
| ['下载安装相关视频编码器Button', '下载安装相关视频编码器', 'Button4']
| child_window(title="下载安装相关视频编码器", class_name="TButton")
|
| ComboBox - 'AAC(推荐)' (L273, T221, R409, B240)
| ['ComboBox1', 'ComboBox0', '下载安装相关视频编码器ComboBox', 'ComboBox']
| child_window(title="AAC(推荐)", class_name="TComboBox")
|
| ComboBox - 'H264(AVC X264) 推荐' (L273, T146, R409, B165)
| ['ComboBox2', 'EXE/EXE 转 MP4ComboBox']
| child_window(title="H264(AVC X264) 推荐", class_name="TComboBox")
|
| TGroupBox - '输出图像尺寸' (L212, T331, R483, B454)
| ['输出图像尺寸TGroupBox', 'TGroupBox2', '输出图像尺寸']
| child_window(title="输出图像尺寸", class_name="TGroupBox")
| |
| | CheckBox - '输出时画面保持原长宽比例' (L286, T433, R436, B447)
| | ['CheckBox2', '输出时画面保持原长宽比例CheckBox', '输出时画面保持原长宽比例']
| | child_window(title="输出时画面保持原长宽比例", class_name="TCheckBox")
| |
| | ComboBox - '' (L314, T410, R457, B429)
| | ['设置为 宽度:ComboBox', 'ComboBox3']
| | child_window(class_name="TComboBox")
| |
| | ComboBox - '1/2' (L314, T369, R396, B388)
| | ['ComboBox4', '按倍数缩小为ComboBox']
| | child_window(title="1/2", class_name="TComboBox")
| |
| | Edit - '300' (L402, T388, R429, B407)
| | ['设置为 宽度:Edit0', '设置为 宽度:Edit', 'Edit5', '设置为 宽度:Edit1']
| | child_window(title="300", class_name="TEdit")
| |
| | Edit - '400' (L314, T388, R341, B407)
| | ['设置为 宽度:Edit2', 'Edit6']
| | child_window(title="400", class_name="TEdit")
| |
| | RadioButton - '设置为 宽度:' (L232, T392, R308, B406)
| | ['设置为 宽度:', '设置为 宽度:RadioButton', 'RadioButton3']
| | child_window(title="设置为 宽度:", class_name="TRadioButton")
| |
| | RadioButton - '按倍数缩小为' (L232, T372, R314, B386)
| | ['RadioButton4', '按倍数缩小为RadioButton', '按倍数缩小为']
| | child_window(title="按倍数缩小为", class_name="TRadioButton")
| |
| | RadioButton - '原始大小' (L232, T351, R287, B366)
| | ['原始大小', '原始大小RadioButton', 'RadioButton5']
| | child_window(title="原始大小", class_name="TRadioButton")
|
| CheckBox - '输出时画面保持原长宽比例' (L286, T433, R436, B447)
| ['CheckBox2', '输出时画面保持原长宽比例CheckBox', '输出时画面保持原长宽比例']
| child_window(title="输出时画面保持原长宽比例", class_name="TCheckBox")
|
| ComboBox - '' (L314, T410, R457, B429)
| ['设置为 宽度:ComboBox', 'ComboBox3']
| child_window(class_name="TComboBox")
|
| ComboBox - '1/2' (L314, T369, R396, B388)
| ['ComboBox4', '按倍数缩小为ComboBox']
| child_window(title="1/2", class_name="TComboBox")
|
| Edit - '300' (L402, T388, R429, B407)
| ['设置为 宽度:Edit0', '设置为 宽度:Edit', 'Edit5', '设置为 宽度:Edit1']
| child_window(title="300", class_name="TEdit")
|
| Edit - '400' (L314, T388, R341, B407)
| ['设置为 宽度:Edit2', 'Edit6']
| child_window(title="400", class_name="TEdit")
|
| RadioButton - '设置为 宽度:' (L232, T392, R308, B406)
| ['设置为 宽度:', '设置为 宽度:RadioButton', 'RadioButton3']
| child_window(title="设置为 宽度:", class_name="TRadioButton")
|
| RadioButton - '按倍数缩小为' (L232, T372, R314, B386)
| ['RadioButton4', '按倍数缩小为RadioButton', '按倍数缩小为']
| child_window(title="按倍数缩小为", class_name="TRadioButton")
|
| RadioButton - '原始大小' (L232, T351, R287, B366)
| ['原始大小', '原始大小RadioButton', 'RadioButton5']
| child_window(title="原始大小", class_name="TRadioButton")
仔细找了一下,文件名后面的编辑框的属性为
| Edit - '' (L259, T88, R429, B107)
| ['EXE/EXE 转 MP4Edit', 'Edit3']
所以我们可以通过控件的text或者title来查找控件。如:
edit = dlg_spec[''] # 1
edit = dlg_spec['Edit2'] # 2
edit = dlg_spec.Edit2 # 3
注意,对于输入控件Edit,一般不建议使用text内容绑定,因为Edit的text内容会发生变化。另外,绑定的控件也可能不唯一。对于title,我这里可能理解不够,属性显示的是Edit3,但实际上绑定的时候用的却是Edit2,也就是数字要减一。
前面已经讲了如何找到一个控件,接下来就是怎么操作它了。对于Edit控件,要么就是向里面写内容,要么就是读里面的内容。
在这里,我们需要向Edit3写入要转换文件的路径(r’E:\test test .exe’),这里的文件名我特意在中间加了空格。
edit.set_text(r'E:\test test .exe') # 1
edit.type_keys(r'E:\test test .exe',with_spaces = True) # 2
上述代码第一种方法是直接设置edit的text,而第二种是在里面模拟键盘输入(如果字符串中没有空格,可以省略后面的参数),殊途同归。

但是实际上,使用第二种方法输入并没有什么效果,因为该编辑框设置了禁止输入(自己手动敲键盘,发现编辑框没有反应)。(这里埋了一个雷,在我们成功将路径写入编辑框的那刻,已经踩着了这颗雷。)
接着配置转换参数。

现在是10帧/秒,建议扩帧后不超过15帧/秒。所以也就没有必要扩帧了。
接着直接模拟点击转换吧。
dlg_spec.Button0.click()
不出所料,弹出“另存为”对话框。

假设我们按照默认的路径存储,那么这里只需要点击“保存”就可以了。
app['另存为']['保存'].click()
注意,所有窗口都应该在app中索引。
执行完上述语句后,发现弹出错误提示。

* 触着的雷终于爆炸了,哈哈!!!*
此路不通,欲知结果如何,接听下回分解。