pywinauto是否有滚动终止API?如何获取列表框全部列表项
pywinauto遍历ListBox全量项滚动逻辑问题修复
问题原因
原代码无法获取全量项的核心原因有4个:
- 存在变量拼写错误:函数入参定义为
lisInstance,循环内调用时写成了listInstace,属于低级笔误。 - 终止判断逻辑有缺陷:仅通过新旧项集合的差集判断是否滚动到底,大部分GUI列表做PageDown滚动时会保留上一页末尾1-2行作为视觉衔接,当列表总长度接近2页时,第一次滚动后差集就会为空,触发提前返回,最终只能拿到一半左右的项。
- 直接用
set处理列表项对象会出现判断误差:pywinauto的列表项实例相等判断依赖运行时状态,直接转集合去重可能出现误判,导致项丢失。 - 没有加渲染等待:滚动后列表需要时间渲染新项,直接读取会拿到未更新的列表内容。
修复后代码
import time def __get_all_items(list_instance): # 初始化首屏项 all_items = list_instance.items() last_item_count = len(all_items) # 连续无新项的重试次数,避免渲染延迟导致误判 no_new_retry = 0 while True: # 向下翻一页 list_instance.scroll("down", "page") # 等待列表渲染,可根据目标应用响应速度调整时长 time.sleep(0.3) current_page_items = list_instance.items() current_count = len(current_page_items) # 连续2次翻页后项总数没有增长,判定已经滚动到底部 if current_count == last_item_count: no_new_retry += 1 if no_new_retry >= 2: # 保序去重,避免set乱序和误判问题 unique_items = [] seen_text = set() for item in all_items: item_text = item.window_text() if item_text not in seen_text: seen_text.add(item_text) unique_items.append(item) return unique_items else: no_new_retry = 0 last_item_count = current_count # 合并当前页的新项 exist_text_set = {i.window_text() for i in all_items} for item in current_page_items: if item.window_text() not in exist_text_set: all_items.append(item) exist_text_set.add(item.window_text())
优化提示
- 如果操作的是标准Win32 ListBox控件,可以直接调用
list_instance.get_item_count()获取总项数,不需要通过滚动遍历的方式收集项,效率更高。 - 如果目标列表存在重复文本的项,可以把去重判断的依据从文本换成项的索引(支持索引获取的控件可以用
list_instance.get_item(i)按索引拿项),避免去重错误。
内容的提问来源于stack exchange,提问作者Christopher Styles
相关产品推荐
相关产品推荐

