鱼C论坛

 找回密码
 立即注册
查看: 1858|回复: 5

怎么输出控件的名字

[复制链接]
发表于 2023-9-1 11:18:51 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x

我想根据"Import Excel"名字来定位到对应的按钮,然后点击该按钮,但是根据以下代码输出的"控件文本:"都是空的
怎么输出所有控件的名字,或者有什么其他的办法可以定位到这个按钮

import win32gui,time
import win32api,win32con

def get_window_controls_info(window_name):
    control_info_list = []

    def callback(hwnd, _):
        control_info = {}
        control_info['hwnd'] = hwnd
        control_info['class_name'] = win32gui.GetClassName(hwnd)
        control_info['text'] = win32gui.GetWindowText(hwnd)
        control_info['rect'] = win32gui.GetWindowRect(hwnd)

        control_info_list.append(control_info)

        return True

    # 查找窗口句柄
    hwnd = win32gui.FindWindow(None, window_name)

    # 遍历窗口的子控件并获取信息
    win32gui.EnumChildWindows(hwnd, callback, None)

    return control_info_list

time.sleep(3)
# 调用函数获取窗口上所有控件的信息
window_name = "出货及开票明细报表"
controls_info = get_window_controls_info(window_name)
for control_info in controls_info:
    print("控件句柄:", control_info['hwnd'])
    print("控件类名:", control_info['class_name'])
    print("控件文本:", control_info['text'])
    print("控件位置和大小:", control_info['rect'])
    print()


输出结果如下:
控件句柄: 328926
控件类名: Afx:58990000:0:00010003:00000010:00000000
控件文本: 
控件位置和大小: (14, 38, 1426, 69)

控件句柄: 394330
控件类名: ComboBox
控件文本: 
控件位置和大小: (54, 43, 196, 65)

控件句柄: 394066
控件类名: Edit
控件文本: 
控件位置和大小: (57, 46, 174, 62)

控件句柄: 263398
控件类名: AfxWnd110
控件文本: 
控件位置和大小: (14, 38, 14, 38)

控件句柄: 920052
控件类名: AfxWnd110
控件文本: 
控件位置和大小: (14, 38, 14, 38)

控件句柄: 1180760
控件类名: AfxWnd110
控件文本: 
控件位置和大小: (14, 69, 1426, 78)


screen_record.png

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-9-1 11:19:37 | 显示全部楼层
在你的代码中,你使用了win32gui.GetWindowText(hwnd)来获取控件的文本,但是输出的结果都是空的。这是因为这个方法只能获取到控件的可见文本,而不是控件的名字。控件的名字通常是在创建控件时指定的,可以通过win32gui.GetClassName(hwnd)来获取。但是在你的代码中,获取到的控件类名都是一些系统默认的类名,而不是控件的名字。

要获取控件的名字,你可以使用win32gui.GetDlgItemText(hwnd, control_id)方法。其中hwnd是窗口的句柄,control_id是控件的ID。控件的ID通常是在创建控件时指定的,你可以查看控件的创建代码来获取ID。

在你的情况下,你可以尝试使用Spy++这个工具来查看窗口的控件树和控件的属性,从而找到"Import Excel"按钮的ID。然后,使用win32gui.GetDlgItemText(hwnd, control_id)方法来获取按钮的名字。

以下是修改后的代码示例:
import win32gui
import win32api
import win32con

def get_window_controls_info(window_name):
    control_info_list = []

    def callback(hwnd, _):
        control_info = {}
        control_info['hwnd'] = hwnd
        control_info['class_name'] = win32gui.GetClassName(hwnd)
        control_info['text'] = win32gui.GetDlgItemText(hwnd, control_id)  # 修改这里
        control_info['rect'] = win32gui.GetWindowRect(hwnd)

        control_info_list.append(control_info)

        return True

    hwnd = win32gui.FindWindow(None, window_name)
    control_id = 1234  # 修改这里,将1234替换为"Import Excel"按钮的ID

    win32gui.EnumChildWindows(hwnd, callback, None)

    return control_info_list

window_name = "出货及开票明细报表"
controls_info = get_window_controls_info(window_name)
for control_info in controls_info:
    print("控件句柄:", control_info['hwnd'])
    print("控件类名:", control_info['class_name'])
    print("控件文本:", control_info['text'])
    print("控件位置和大小:", control_info['rect'])
    print()

请注意,你需要将1234替换为"Import Excel"按钮的实际ID。你可以使用Spy++等工具来查看按钮的ID。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-9-1 11:57:06 | 显示全部楼层
本帖最后由 lengyue869 于 2023-9-1 13:40 编辑
isdkz 发表于 2023-9-1 11:19
在你的代码中,你使用了win32gui.GetWindowText(hwnd)来获取控件的文本,但是输出的结果都是空的。这是因为 ...


报错了......



---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-9-d0f2e59699fe> in callback(hwnd, _)
     11         control_info['class_name'] = win32gui.GetClassName(hwnd)
---> 12         control_info['text'] = win32gui.GetDlgItemText(hwnd, control_id)  # 修改这里
     13         control_info['rect'] = win32gui.GetWindowRect(hwnd)

TypeError: an integer is required (got type str)

The above exception was the direct cause of the following exception:

SystemError                               Traceback (most recent call last)
<ipython-input-9-d0f2e59699fe> in <module>
     25 
     26 window_name = "出货及开票明细报表"
---> 27 controls_info = get_window_controls_info(window_name)
     28 for control_info in controls_info:
     29     print("控件句柄:", control_info['hwnd'])

<ipython-input-9-d0f2e59699fe> in get_window_controls_info(window_name)
     20     control_id = "0000009C"  # 修改这里,将1234替换为"Import Excel"按钮的ID
     21 
---> 22     win32gui.EnumChildWindows(hwnd, callback, None)
     23 
     24     return control_info_list

SystemError: <built-in function EnumChildWindows> returned a result with an error set

screenshot.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-9-1 17:41:56 | 显示全部楼层
看你需求,如果不复杂的话,只是点击几个可见按钮,更简单的方式,可以用 opencv 基于图片直接识别出来按钮,再用pyautogui点击即可

ps: 反正我已经试过你的这个 Import Excel按钮,用opencv-python库是可以很快识别到的,加上点击,也总共才十来行代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-9-2 19:52:06 | 显示全部楼层
阿奇_o 发表于 2023-9-1 17:41
看你需求,如果不复杂的话,只是点击几个可见按钮,更简单的方式,可以用 opencv 基于图片直接识别出来按钮 ...

这个是数据查询完成之后的界面,我其实想根据出现Import Excel这个按钮来判断数据是否加载完成,然后用pyautogui点击导出数据,
之所以不用图片识别是因为要最终程序要打包成exe发给别人用,要把图片打包进去,然后还存在不同的显示器分辨率可能导致图片识别不准
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-9-2 23:14:21 | 显示全部楼层
lengyue869 发表于 2023-9-2 19:52
这个是数据查询完成之后的界面,我其实想根据出现Import Excel这个按钮来判断数据是否加载完成,然后用pyau ...

这样呀。。 如果 没具体程序来试验,那还真不好搞。。

另外对Windows视窗UI等,不熟悉的,也增加了开发难度。。

还有,Spy++能监测到,pywin32不一定都能。。  

so, 你自己再琢磨琢磨吧,暂时帮不了你  ^_^
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-14 15:45

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表