圆孔毛刺检测系统:UI自动化与外部控制集成

检测软件自己跑完了,还得让外部定位软件动起来。

uiautomation、控件查找、缓存机制、配置管理——一个不少。

一、业务场景

检测系统需要与外部定位软件(如显微镜控制软件)联动:

  1. 自动填入检测到的圆心坐标

  2. 发送坐标到外部软件

  3. 触发定位操作(显微镜移动到目标位置)

一句话:检测完了,告诉机器去哪儿看。


二、uiautomation简介

Windows平台上操作原生控件的库。

2.1 安装

bash

pip install uiautomation

2.2 核心能力

  • AutomationId查找控件

  • Name查找控件

  • 控件缓存(避免重复查找)


三、ExternalController类

3.1 类结构

python

class ExternalController:
    def __init__(self):
        # 控件标识(支持AutomationId和Name两种方式)
        self.x_edit_automation_id = ''
        self.y_edit_automation_id = ''
        self.locate_button_automation_id = ''
        self.x_edit_name = ''
        self.y_edit_name = ''
        self.locate_button_name = ''
        
        # 缓存机制
        self.cached_window = None
        self.cached_x_edit = None
        self.cached_y_edit = None
        self.cached_locate_button = None
        self.cache_time = 0
        self.cache_timeout = 600   # 10分钟
        
    def set_controls(self, x_edit_automation_id='', y_edit_automation_id='', 
                     locate_button_automation_id='', x_edit_name='', 
                     y_edit_name='', locate_button_name=''):
        self.x_edit_automation_id = x_edit_automation_id
        self.y_edit_automation_id = y_edit_automation_id
        self.locate_button_automation_id = locate_button_automation_id
        self.x_edit_name = x_edit_name
        self.y_edit_name = y_edit_name
        self.locate_button_name = locate_button_name
        self.clear_cache()

3.2 核心方法

方法功能
set_controls()配置控件标识
set_xy(x, y)填入坐标并触发定位
clear_cache()清除控件缓存
save_config()保存配置到QSettings

四、控件查找(双重机制)

python

def _find_control(self, automation_id, name, control_type, parent):
    # 方式一:按AutomationId查找
    try:
        if automation_id:
            control = parent.Control(searchDepth=1, AutomationId=automation_id)
            if control.Exists(0.2):
                return control
    except:
        pass
    
    # 方式二:按Name查找
    try:
        if name:
            control = parent.Control(searchDepth=1, Name=name, ControlType=control_type)
            if control.Exists(0.2):
                return control
    except:
        pass
    
    return None

两种方式任选一种配置即可

控件AutomationId方式Name方式
X输入框x_edit_automation_idx_edit_name
Y输入框y_edit_automation_idy_edit_name
定位按钮locate_button_automation_idlocate_button_name

五、定位执行

python

def set_xy(self, x, y):
    try:
        x_edit = self._get_x_edit()
        y_edit = self._get_y_edit()
        locate_button = self._get_locate_button()
        
        if not x_edit or not y_edit or not locate_button:
            return False, '无法找到目标控件'
        
        # 填入坐标(保留两位小数)
        x_edit.SetValue(f'{x:.2f}')
        y_edit.SetValue(f'{y:.2f}')
        
        # 点击定位按钮
        locate_button.Click()
        
        return True, '定位成功'
    except Exception as e:
        return False, str(e)

六、缓存机制

6.1 缓存有效性

python

def _is_cache_valid(self):
    if time.time() - self.cache_time < self.cache_timeout:
        return True
    return False

def _update_cache_time(self):
    self.cache_time = time.time()

6.2 为什么需要缓存

优势说明
性能提升避免每次调用都重新查找控件
响应更快直接使用缓存的控件引用
资源节省减少系统调用开销

6.3 控件获取(带缓存)

python

def _get_x_edit(self):
    if self._is_cache_valid():
        return self.cached_x_edit
    
    window = self._get_window()
    if not window:
        return None
    
    self.cached_x_edit = self._find_control(
        self.x_edit_automation_id, 
        self.x_edit_name, 
        uiautomation.ControlType.Edit, 
        window
    )
    self._update_cache_time()
    return self.cached_x_edit

七、配置管理(QSettings)

7.1 保存配置

python

def save_config(self):
    settings = QSettings('BurrDetection', 'ExternalControl')
    settings.setValue('x_edit_automation_id', self.x_edit_automation_id)
    settings.setValue('y_edit_automation_id', self.y_edit_automation_id)
    settings.setValue('locate_button_automation_id', self.locate_button_automation_id)
    settings.setValue('x_edit_name', self.x_edit_name)
    settings.setValue('y_edit_name', self.y_edit_name)
    settings.setValue('locate_button_name', self.locate_button_name)
    settings.sync()

7.2 加载配置

python

def load_config(self):
    settings = QSettings('BurrDetection', 'ExternalControl')
    self.x_edit_automation_id = settings.value('x_edit_automation_id', '', type=str)
    self.y_edit_automation_id = settings.value('y_edit_automation_id', '', type=str)
    self.locate_button_automation_id = settings.value('locate_button_automation_id', '', type=str)
    self.x_edit_name = settings.value('x_edit_name', '', type=str)
    self.y_edit_name = settings.value('y_edit_name', '', type=str)
    self.locate_button_name = settings.value('locate_button_name', '', type=str)

八、主窗口集成

8.1 发送定位按钮

python

def send_xy_and_locate(self):
    self.btn_send_xyz.setEnabled(False)
    
    # 读取坐标
    try:
        x = float(self.edit_x.text())
        y = float(self.edit_y.text())
    except ValueError:
        QMessageBox.warning(self, '警告', '请输入有效的XY坐标')
        self.btn_send_xyz.setEnabled(True)
        return
    
    # 执行定位
    success, msg = self.external_controller.set_xy(x, y)
    self.btn_send_xyz.setEnabled(True)
    
    if not success:
        QMessageBox.warning(self, '错误', msg)
        return
    
    # 更新表格状态
    if self.current_image_index >= 0:
        status_item = self.table.item(self.current_image_index, 1)
        if status_item and status_item.text() == '已检测':
            sent_item = QTableWidgetItem('已发送')
            sent_item.setBackground(Qt.GlobalColor.yellow)
            self.table.setItem(self.current_image_index, 1, sent_item)

九、错误处理

9.1 常见错误及原因

错误原因解决方法
控件未找到外部软件未启动先启动外部软件
控件未找到AutomationId/Name配置错误用uiautomation工具检查
权限不足uiautomation需管理员权限以管理员身份运行
控件失效外部软件界面更新清除缓存重新查找

9.2 异常捕获

所有外部操作都包在try-except中,避免因外部软件异常导致主程序崩溃。

python

try:
    # uiautomation操作
except Exception as e:
    return False, str(e)

十、踩坑记录

  1. 管理员权限:uiautomation操作外部进程控件,必须以管理员身份运行

  2. 控件标识获取:用uiautomation自带的Inspect工具查看控件的AutomationId和Name

  3. 缓存失效:外部软件重启后,缓存的控件引用会失效,要清除缓存

  4. 超时设置Exists(0.2)设置0.2秒超时,避免长时间等待

  5. 控件查找深度searchDepth=1只查直接子控件,避免查找到同名控件


下篇预告

下一篇写批量处理与多线程:QThread、信号槽、任务队列、进度反馈。

如果对外部控制有不同思路,评论区聊。

内容概要:本文围绕“考虑电动汽车聚合可调节能力的含波动性电源电氢耦合系统多目标优化运行”展开研究,提出了一种基于Matlab代码实现的多目标优化模型。该模型深度融合电-氢耦合系统高比例波动性可再生能源(如风电、光伏),充分挖掘电动汽车(EV)集群作为移动储能单元的灵活调节潜力,通过聚合调控提升系统对新能源的消纳能力运行经济性。研究系统构建了电动汽车可调度能力、电解水制氢储氢动态过程、多能源协同互补的优化调度框架,并结合智能优化算法实现经济性、低碳性运行稳定性等多重目标的协同优化。文中配套提供了完整的Matlab仿真代码、相关数据及可能的论文支撑材料,极大地方便了模型的复现、验证后续深化研究。; 适合人群:具备电力系统、综合能源系统、优化理论或新能源技术等相关领域基础知识的研究生、科研人员,以及从事新型电力系统规划、清洁能源消纳智慧能源管理的工程技术人员。; 使用场景及目标:①开展高渗透率可再生能源接入下的综合能源系统多目标优化调度研究;②探究电动汽车集群在电网削峰填谷、平抑新能源出力波动及提供辅助服务方面的应用价值潜力;③学习并掌握电氢耦合系统的建模方法、多目标优化求解技术及其在Matlab/Simulink环境下的仿真实现流程。; 阅读建议:此资源不仅提供可运行的代码,更蕴含了前沿的科研思路创新方法,建议读者结合所提供的代码、数据可能的论文文档,系统性地学习从问题建模、算法设计到仿真分析的完整科研过程,并重点关注其中关于需求侧资源聚合、多能互补协同绿色低碳运行的核心理念。
内容概要:本文档名为《经济学期刊论文复现:数字化转型能促进企业的高质量发展吗》,表面上聚焦于经济学领域中数字化转型对企业高质量发展影响的研究,实则是一份涵盖多学科交叉的科研仿真代码资源合集。资源以Matlab、Simulink、Python为主要工具,系统整合了电力系统仿真、微电网优化调度、路径规划、信号处理、图像处理、机器学习预测模型等方向的可复现算法仿真模型。尽管标题指向经济学实证分析,但内容重心在于提供顶级期刊论文的复现代码,如企业全要素生产率(TFP)测算方法(OL、FE、LP、OP、GMM)、风光储氢系统优化、需求响应综合能源系统调度等,并融合智能优化算法深度学习技术进行数据建模预测分析,体现出极强的工程化科研实用性。; 适合人群:具备一定编程基础,熟练掌握Matlab/Simulink/Python等仿真工具,从事工程仿真、经济实证研究或交叉学科科研工作的研究生、高校教师及科研人员。; 使用场景及目标:① 复现经济学顶刊论文中的计量经济模型,深入探究数字化转型对企业全要素生产率的影响机制;② 借助提供的代码资源开展电力系统故障仿真、微电网优化、多能系统调度等科研项目的算法验证仿真分析;③ 应用机器学习深度学习模型完成负荷预测、风电光伏出力预测、电池健康状态评估等典型实证任务; 阅读建议:此资源虽冠以经济学论文之名,实质为多领域高价值仿真代码集成,建议读者依据自身研究方向筛选适配内容,优先关注“顶刊复现”“论文复现”类项目,结合配套数据代码进行实证推演,并通过公众号“荔枝科研社”获取完整资料持续技术支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

在世修行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值