如何使用pywinauto监听Listbox变化以响应游戏服务器GUI事件
实现方案
pywinauto没有内置的控件内容变更监听接口,针对你的游戏服务器GUI场景,最易落地的是增量轮询比对方案,逻辑为定期拉取Listbox全量内容,和上一次缓存的内容做差异对比,识别到新增行后触发对应处理逻辑,完全能满足你监听玩家加入、自动发欢迎消息的需求。
可直接修改使用的示例代码
from pywinauto import Application import time # 1. 初始化连接,替换为你实际的程序路径和窗口标题 app = Application(backend="uia").connect(path=r"C:\Program Files (x86)\___.exe") dlg = app.window(title="替换为你的服务器窗口实际标题") # 校验控件是否正常识别 assert dlg.ListBox.exists(), "未识别到ListBox控件" assert dlg.Edit.exists(), "未识别到Edit输入控件" # 2. 缓存初始状态的ListBox内容 def get_listbox_content(): return [item.window_text() for item in dlg.ListBox.descendants()] last_content = get_listbox_content() # 3. 自定义触发规则,可根据你的实际日志格式修改 TRIGGER_RULES = { # 匹配玩家加入的日志关键词,替换为你实际日志里的对应字符串 "加入服务器": lambda player_name: send_welcome_msg(player_name) } def send_welcome_msg(player_name): """发送欢迎消息的处理函数,可自行修改命令格式""" welcome_cmd = f"say 欢迎{player_name}加入服务器!" dlg.Edit.set_text(welcome_cmd) # 如果需要按回车发送,加上下面这句 # dlg.Edit.type_keys("{ENTER}") # 4. 轮询监听循环 POLL_INTERVAL = 1 # 轮询间隔,单位秒,可根据需求调整 print("已启动监听,按Ctrl+C终止") try: while True: current_content = get_listbox_content() # 找新增的行 new_lines = [] if len(current_content) > len(last_content): new_lines = current_content[len(last_content):] elif current_content != last_content: # 处理内容被清空后重写的场景 new_lines = current_content # 遍历新增行匹配触发规则 for line in new_lines: print(f"新增日志: {line}") for keyword, handler in TRIGGER_RULES.items(): if keyword in line: # 简易提取玩家名,可根据你的日志格式正则匹配优化 player_name = line.split(keyword)[0].strip() handler(player_name) break # 更新缓存 last_content = current_content time.sleep(POLL_INTERVAL) except KeyboardInterrupt: print("监听已终止")
优化建议
- 若服务器日志刷新频率低,可适当调大
POLL_INTERVAL参数,降低CPU占用 - 可以扩展
TRIGGER_RULES字典,新增关键词和对应处理函数,支持监听玩家退出、指令请求等更多场景 - 如果ListBox行数过多,可仅比对行数变化,仅当行数增加时才拉取新增行,不需要每次全量读取所有内容,效率更高
进阶方案(适合有Win32开发基础的场景)
如果你的ListBox是标准Win32控件,也可以通过hookWM_COMMAND消息监听LBN_INSERTSTRING事件实现事件驱动的监听,不需要轮询,但实现复杂度高,对自定义绘制的非标准控件兼容性差,普通场景使用轮询方案即可。
内容的提问来源于stack exchange,提问作者daulip
相关产品推荐
相关产品推荐

