【日常学习】2025 8-29 认识输入控件设计模式

零、核心协作链路

1.用例触发输入 :用例创建 Input 实例,调用 input() 方法;有新项目了,管理层要指挥人干活

2.Input 调度适配Input 通过 get_app_input() 识别应用为 "hsy",创建 HsyInput 实例;管理层看了一下员工是A类的,那就让他以A类的标准去完成这个活。

3.HsyInput 匹配控件

HsyInput.getInputCtrl() 识别场景为 "表单输入",调用 CtrlManager.getCtrl(ctrl_html, parent);员工A看了一下具体什么活,就去找零件仓库管理员拿对应这个活需要的零件。

CtrlManager 遍历注册控件,匹配到 FormComp(因 ctrl_html 含表单特征),返回 FormComp 实例;仓库管理员找遍仓库,给到员工A这个活需要的具体零件

4. FormComp 执行输入HsyInput 调用 FormComp.input(value)FormComp 继承 InputCtrlBase 的通用逻辑,同时执行表单校验;员工A使用这个零件干活,这个零件是符合老板InputCtrlBase的规定的,很安全可以放心使用。

返回结果 :输入完成后,HsyInputFormComp 的执行结果返回给用例。员工A把干完活得到的成果给到了新项目(测试用例中有输入动作的部分)去使用。

  • 最基本的:老板,【管理层,工人(分类)】,仓库管理员,零件。
  • 工人继承管理层(管理人员和工人都是员工,当然和老板不一样,但是管理人员是父类,是上级)
  • 零件继承老板,因为零件是依照老板的规矩定制的。

学习时,从 "用例调用流程" 反向推导,先看 Input.py 的调度逻辑,再深入 HsyInput 的具体实现,最后补全 InputCtrlBase 的抽象规范,就能彻底打通输入控件的设计思路!

1. InputCtrlBase.py:输入控件的 "抽象接口"(规矩制定者)
  • 定位 :所有输入控件的基类 / 接口 ,定义输入操作的 "标准动作"(如 inputtext),强制子类实现。
  • 核心作用
    • 规定输入控件必须有 input(执行输入)、text(获取值)等方法,确保所有输入控件 "接口统一";
    • 封装输入场景的通用逻辑(如输入值适配、弹窗处理),子类继承后直接复用,无需重复编码。
  • 类比 :手机的 "Type-C 接口标准"------ 规定了充电、传数据的统一方式,所有充电头 / 线必须遵守。干活人该干什么,活干完达成什么目标。
2. Input.py:输入操作的 "调度中心"(指挥官)
  • 定位 :不直接执行输入,而是根据 "应用类型""输入参数" 动态选择具体的输入实现 (如 HsyInputTcH5Input)。
  • 核心作用
    • 接收输入参数(输入值、类型、期望值等),集中管理;
    • 通过 get_app_input() 判断当前应用(如 hsyTcH5),创建对应的 HsyInput/TcH5Input 实例;
    • 对外提供统一的 input 方法,屏蔽 "不同应用输入逻辑差异",让用例只需调用 Input().input(...)
  • 类比 :"充电线 + 智能识别芯片"------ 插入手机后,自动识别设备类型(安卓 /iOS),调度对应的充电协议。把目标细化,不同的有不同的处理方式。根据谁是什么人,活有不同的干法,使得最终都达成想要目标的结果。
3. HsyInput.pyhsy 应用的 "输入执行者"(hsy 充电头)
  • 定位 :继承 Input 类,专门处理 hsy 应用(如好会计)的输入逻辑
  • 核心作用
    • 根据 inputType(输入类型:直接输入、扫码、参照输入等)和页面 ctrl_html(HTML 特征),匹配具体的输入控件(如文本框、扫码组件、参照选择器);
    • 调用 getInputCtrl 找到控件后,执行实际输入操作(如 InputComp.input() 输入文本、ScanInputComp.input() 扫码)。
  • 类比 :"安卓充电头"------ 识别到安卓手机后,启动安卓充电协议,执行充电。干活人A具体如何达成这个目标。
4. TcH5Input.pyTcH5 应用的 "输入执行者"(TcH5 充电头)
  • 定位 :和 HsyInput 平级,专门处理 TcH5 应用的输入逻辑(代码未贴,但逻辑对称)。
  • 核心作用
    • 根据 TcH5 应用的页面特征(HTML 结构、控件类名),匹配对应的输入控件;
    • 执行 TcH5 场景下的输入操作(如 H5 页面的文本输入、下拉选择)。
  • 类比 :"iOS 充电头"------ 识别到苹果手机后,启动 Lightning 充电协议,执行充电。干活人B具体如何达成这个目标。

一、工人

(1)第一步,把管理层给的要点完全记下来,不遗漏,不自创。

python 复制代码
def __init__(self, inputType=None, expect=None, value=None, ctrl=None, data=None, fuzzySearch=None):
    self.inputType = inputType  # 输入类型(如直接输入、参照输入)
    self.expect = expect if expect is not None else value  # 期望值
    self.data = value if data is None else data  # 新页面参数
    self.value = value  # 输入值
    self.fuzzySearch = fuzzySearch  # 模糊搜索参数
    self.ctrl = ctrl  # 关联的具体控件实例(后续会通过 getInputCtrl 找到)
  • Input 基类的 __init__ 完全一致,目的是 "无缝接收基类传递的所有输入参数",确保参数在 "调度中心→执行者" 之间完整传递。
  • 没有新增参数,说明 HsyInput 专注于 "执行" 而非 "参数管理",符合单一职责原则。

(2)根据这些要点,经常干的活自己就知道零件在哪直接拿出来用,有些零件不知道具体该用啥就要去让仓库管理员在仓库给他找。

这是 HsyInput 最关键的方法,"根据输入类型(inputType)和页面 HTML(ctrl_html)特征,自动匹配并返回对应的具体输入控件实例"(如文本框控件、扫码控件),解决 "不同输入场景需要不同控件" 的问题。

python 复制代码
def getInputCtrl(self, parent=None, ctrl_html=None):
   

    # 1. 匹配"直接输入"场景(最常用的文本输入)
    if ((self.inputType is None ...


        # 普通文本输入框,返回 InputComp 控件
        return InputComp.instance(parent)

    # 2. 匹配"区间输入"场景(如日期区间、金额区间)
    elif self.inputType == InputType.区间输入:
        return BetweenInputCtrl.instance(parent)

    # 3. 匹配"扫码输入"场景(通用扫码)
    elif self.inputType == InputType.扫码输入:
        return ScanInputComp.instance(parent)
     
    ...

    # 其他场景:由控件管理器自动匹配
    else:
        return CtrlManager.getCtrl(ctrl_html, parent)

    # 所有条件都不匹配,抛出异常
    raise Exception("没有找到输入控件")
设计亮点:
  1. "输入类型 + HTML 特征" 双重判断

    不仅根据 inputType 匹配(如 InputType.扫码输入 对应 ScanInputComp),还结合 ctrl_html(控件 HTML 源码)的特征(如 'input' in ctrl_html 说明是文本框,'Select-arrow-zone' 说明是下拉参照),确保匹配的控件准确无误。

  2. 优先级处理

    "直接输入" 场景放在最前面,因为它是最常用的场景;特殊场景(如带下拉箭头的输入框)做单独判断,避免误判为普通文本框。

  3. 单例模式(instance(parent)

    所有控件通过 instance(parent) 获取实例(而非直接 __init__),确保每个控件在同一父容器下只有一个实例,避免重复创建,节省资源。控件和父容器绑定,控件有了上下文,驱动,就像不同的零件在不同的机械中发挥恰当的作用。

  4. 控件管理器(CtrlManager)兜底

    复杂场景(如 InputType.参照输入)由 CtrlManager 统一管理,减少 HsyInput 的代码冗余,符合 "单一职责" 原则。

(3)拿零件回来了,回到工位开始忙活。

在找到具体控件(self.ctrl)后,input 方法负责 "调用控件的输入逻辑,执行实际操作,并返回最终的期望值"

python 复制代码
def input(self, parent=None, elementParent=None, ctrl_html=None, key=None):
    # 1. 如果还没找到控件,调用 getInputCtrl 匹配
    if self.ctrl is None:
        self.ctrl = self.getInputCtrl(parent, ctrl_html)
    
    # 2. 等待控件加载(短暂休眠,避免操作过快)
    time.sleep(0.5)
    
    # 3. 给控件绑定父容器(用于定位)
    self.ctrl.elementParent = elementParent
    self.ctrl.parent = parent
    
    # 4. 处理模糊搜索场景
    if self.fuzzySearch is not None:
        self.ctrl.fuzzyInput(self.fuzzySearch)  # 调用控件的模糊搜索方法
    
    # 5. 普通输入场景
    else:
        self.ctrl.key = key  # 绑定业务键(如"客户名称")
        self.ctrl.real_data = None  # 清空实际数据缓存
        # 调用控件的 input 方法执行输入(用 data 或 value 作为输入值)
        expect = self.ctrl.input(self.value if self.data is None else self.data)
        time.sleep(0.5)  # 等待输入完成
        
        # 6. 更新期望值(如果控件返回了实际结果,以实际结果为准)
        if expect:
            self.expect = None  # 控件已处理期望,这里置空
        if self.ctrl.real_data:  # 控件有实际输入的数据(如参照选择后返回的ID)
            self.expect = self.ctrl.real_data  # 用实际数据更新期望值
    
    # 7. 返回最终的期望值和控件实例(供后续断言或操作)
    return self.expect, self.ctrl
关键逻辑:
  • 控件绑定父容器elementParentparent 是控件的定位上下文(如父页面、父组件),确保控件能正确找到页面元素。
  • 模糊搜索与普通输入分离 :模糊搜索调用 fuzzyInput 方法,普通输入调用 input 方法,逻辑清晰。
  • 期望值动态更新 :输入后如果控件返回了 real_data(如参照选择后实际选中的 ID,而非显示的名称),则用 real_data 作为最终期望值,确保断言准确。

(4)忙活完了把成果返回给管理层Input,管理层再给到项目(用例)

对应测试用例的一行代码调用。

二、管理员

一、核心功能:集中信息;抽象目标拆解为实际目标;智慧用人。

python 复制代码
def __init__(self, inputType=None, expect=None, value=None, ctrl=None, data=None, fuzzySearch=None) -> None:
    self.inputType = inputType  # 输入类型(如直接输入、扫码输入,对应 InputType 枚举)
    self.expect = expect if expect is not None else value  # 输入后的期望值(默认等于输入值)
    self.data = value if data is None else data  # 新页面需要的参数(如跳转后页面的初始化数据)
    self.value = value  # 实际输入的值(如文本框中要输入的内容)
    self.fuzzySearch = fuzzySearch  # 模糊搜索参数(如 {"模糊搜索": True, "具体匹配": "关键词"})
    self.ctrl = ctrl  # 关联的控件实例(如输入框控件,用于定位具体元素)
    self.input_obj = None  # 实际执行输入的对象(HsyInput 或 TcH5Input,延迟初始化)
  • 如果目标是普通输入,类的实例化对象就是 Input(inputType,parent)
  • 如果目标是字典输入,类的实例化就先调用Input类方法buildInput,这个类方法处理字典为data参数,放在实例化函数中,再进行实例化。
⭐ get_app_input 方法:根据应用类型适配具体输入对象 根据集中的信息智慧用人
python 复制代码
def get_app_input(self):
    from script.common.AppInput.HsyInput import HsyInput
    from script.common.AppInput.TcH5Input import TcH5Input
    # 根据当前运行的应用(从上下文获取)选择对应的输入实现类
    if RunContext.getRunContext().app in ['ydz','hsy', 'cc', 'zhijia', 'hkj', 'xsc', 'retail']:
        self.input_obj = HsyInput(...)  # 适配"好会计"等应用的输入逻辑
    elif RunContext.getRunContext().app in ['TcH5']:
        self.input_obj = TcH5Input(...)  # 适配"TcH5"应用的输入逻辑
    else:
        raise Exception("没有找到输入控件")
    return self.input_obj
⭐ input 方法:统一的输入执行入口 放眼整体,这个项目好不好确实看的是管理层(部门领导)做的咋样。
python 复制代码
def input(self, parent=None, elementParent=None, ctrl_html=None, key=None):
    return self.get_app_input().input(parent, elementParent, ctrl_html, key)
  • 作用 :对外提供统一的 input 方法,内部调用具体输入对象(HsyInputTcH5Input)的 input 方法执行实际输入。
  • 优势 :用例无需关心 "当前应用需要调用哪个输入类",只需调用 Input().input(...) 即可,屏蔽了应用差异。
⭐ buildInput 静态方法:从字典数据构建 Input 实例 好的leader是啥抽象目标来了都能接住分析整理好成可执行的目标。
python 复制代码
@staticmethod
def buildInput(data):
    inputType = data[Keys.输入方式] if Keys.输入方式 in data else None
    expect = data[Keys.期望值] if Keys.期望值 in data else None
    fuzzySearch = {"模糊搜索":data[Keys.模糊搜索],"具体匹配":data[Keys.具体匹配]} if Keys.模糊搜索 in data else None
    data = data[Keys.输入值] if Keys.输入值 in data else None
    return Input(inputType=inputType, expect=expect, data=data, fuzzySearch=fuzzySearch)
  • 作用 :快速将 "字典格式的输入配置"(如测试用例中的 JSON 数据)转换为 Input 实例,简化用例编写。
  • 场景 :测试用例可能用字典定义输入(如 {"输入方式": "参照输入", "输入值": "张三", "期望值": "张三"}),通过 buildInput 直接转换成可执行的 Input 对象。

二、相关枚举类:规范输入场景的 "常量定义"

枚举类(InputTypeExpectTypeconfirmAction)的核心作用是 "用常量替代硬编码字符串",避免拼写错误,同时让代码更易读、易维护。

1. InputType:定义所有支持的输入方式
python 复制代码
class InputType(Enum):
    直接输入 = None  # 普通文本输入(如 input 标签的键盘输入)
    扫码输入 = "扫码输入"  # 扫码枪输入(如商品条码扫描)
    商品条码输入 = "商品条码输入"  # 专门针对商品条码的输入
    参照输入 = "参照输入"  # 从参照列表选择(如下拉框选择客户)
    参照新增 = "参照新增"  # 从参照列表新增选项(如新增客户后选择)
    区间输入 = "区间输入"  # 输入范围(如日期区间、金额区间)
    好会计页面新增 = "好会计页面新增"  # 好会计应用的页面内新增操作
    批量修改为 = "批量修改为"  # 批量修改多个元素的值
    打开参照 = "打开参照"  # 仅打开参照列表,不选择具体值
  • 作用 :明确框架支持的所有输入方式,用例通过 InputType.直接输入 引用,比直接写字符串 None 更清晰,且 IDE 会提示补全,减少错误。
2. ExpectType:定义输入后的期望结果类型
python 复制代码
class ExpectType(Enum):
    提示框 = "提示框"  # 输入后弹出提示(如"输入成功")
    弹窗 = "弹窗"  # 输入后弹出新窗口(如选择客户的弹窗)
  • 作用 :配合 Inputexpect 属性,明确输入后需要验证的结果类型(是提示框还是弹窗),后续由 _handleConfirmExpect 方法处理。

⭐ 整体设计逻辑:"门面模式" 简化输入操作

Input 类的设计采用了 "门面模式" (Facade Pattern)------ 对外提供一个简单统一的接口(input 方法),内部协调复杂的子系统(HsyInputTcH5Input 等具体实现),让用例无需了解底层细节。

用例视角:调用流程极简
python 复制代码
# 1. 简单输入:直接输入文本
input_obj = Input(inputType=InputType.直接输入, value="张三")
input_obj.input(parent=page, ctrl_html=html)  # 自动适配当前应用的输入逻辑

# 2. 从字典构建:适合测试用例的JSON数据
data = {"输入方式": InputType.参照输入, "输入值": "李四", "期望值": "李四"}
input_obj = Input.buildInput(data)
input_obj.input(...)
框架视角:内部逻辑清晰
  1. 用例调用 Input().input(...)
  2. Input 通过 get_app_input() 确定当前应用(如 "hsy"),创建对应 HsyInput 对象;
  3. 调用 HsyInput.input(...) 执行具体输入(如参照输入的 "打开参照列表→选择选项→确认");
  4. 若有 expect 且包含弹窗 / 提示框,由 _handleConfirmExpect 自动处理。

⭐ 核心价值总结

  1. 统一接口 :不管是哪种输入方式(直接输入、扫码输入)、哪个应用(hsy、TcH5),用例都用 Input().input() 调用,降低学习成本;
  2. 场景适配 :通过 RunContextget_app_input 动态适配不同应用的输入逻辑,避免代码重复;
  3. 参数集中管理 :所有输入相关参数(值、类型、期望结果)都在 Input 实例中,逻辑清晰,便于调试;
  4. 枚举规范:用枚举替代硬编码,减少错误,提高代码可读性和可维护性。

三、仓库管理员

一、核心定位:控件的 "注册中心 + 调度中心"

想象框架中的控件(如 InputCompCanZaoSelectCtrl)、弹窗(如 ConfirmBase 子类)是 "零散的零件",CtrlManager 就是 "零件仓库 + 调度员":

  • 仓库 :通过 addComp/addConfirm 等方法,将所有控件 / 弹窗 "登记入库";
  • 调度员 :通过 getCtrl/hasConfirmShow 等方法,根据页面特征(如 ctrl_html)从仓库中找到 "匹配的零件",并返回可用实例。

它的存在让框架从 "硬编码调用控件"(如 InputComp.instance(parent))升级为 "动态匹配控件"(如 CtrlManager.getCtrl(ctrl_html, parent)),大幅提升扩展性。

二、核心功能:三大模块(控件管理、弹窗管理、参照控件管理)

CtrlManager 围绕 "控件" 和 "弹窗" 设计了三大核心功能,每个功能都包含 "注册" 和 "获取" 两个操作,形成闭环。

复制代码
def getCtrl(cls, ctrl_html, parent):
    """
    初始化具体控件,设置父组件
    """
    ctrl_list = []
    for comp in cls.components():

        if comp.is_this_ctrl(ctrl_html):
            ctrl_list.append(comp.instance(parent))
1. 业务控件管理(最核心):动态匹配输入 / 选择类控件

负责管理所有业务控件(如文本输入框、下拉选择器、参照控件),核心是 getCtrl 方法 ------ 根据页面 HTML 特征(ctrl_html),找到并返回匹配的控件实例。

(1)关键方法拆解
方法名 作用 核心逻辑
addComp(cls) 向 "控件仓库" 注册控件类(如 InputCompCanZaoSelectCtrl 将控件类(而非实例)添加到 __components 列表,供后续匹配使用。
components() 获取所有已注册的控件类 返回 __components 列表,是 getCtrl 方法的 "数据源"。
getCtrl(ctrl_html, parent) 核心!根据 ctrl_html 匹配控件,并返回实例 1. 遍历所有已注册的控件类; 2. 调用控件类的 is_this_ctrl(ctrl_html) 方法,判断该控件是否匹配当前 HTML 特征; 3. 收集所有匹配的控件实例,按规则返回(1 个则返回,0 个返回默认 InputComp,多个返回第一个并报警)。
(2)逻辑示例(结合之前的 HsyInput

HsyInput.getInputCtrl 中,曾调用 CtrlManager.getCtrl(ctrl_html, parent) 匹配参照控件,背后逻辑是:

Matlab 复制代码
# 1. 假设已注册参照控件 CanZaoSelectCtrl(通过 @register_comp 装饰器)
# 2. 当调用 CtrlManager.getCtrl(ctrl_html, parent) 时:
#    a. 遍历 __components 中的所有控件类(包括 CanZaoSelectCtrl);
#    b. 调用 CanZaoSelectCtrl.is_this_ctrl(ctrl_html),判断 ctrl_html 中是否有"参照控件的特征"(如 class 含"refer");
#    c. 若匹配,返回 CanZaoSelectCtrl.instance(parent) 实例;
#    d. 若不匹配,继续遍历其他控件,最终返回默认 InputComp。
2. 确认弹窗管理:统一检测与实例化弹窗

负责管理所有业务弹窗(如 "确认删除" 弹窗、"提示成功" 弹窗),核心是 hasConfirmShow 方法 ------ 检测当前页面是否有弹窗显示,并返回对应的弹窗实例。

关键方法拆解
方法名 作用 核心逻辑
addConfirm(cls) 向 "弹窗仓库" 注册弹窗类(如 DeleteConfirmSuccessConfirm 将弹窗类添加到 __confirmModes 列表。
confirms() 获取所有已注册的弹窗类 返回 __confirmModes 列表,是 hasConfirmShow 的 "数据源"。
hasConfirmShow() 检测当前页面是否有弹窗,并返回弹窗实例 1. 遍历所有已注册的弹窗类; 2. 调用弹窗类的 is_show() 方法,判断弹窗是否在当前页面显示; 3. 若找到显示的弹窗,返回其实例; 4. 若未找到,返回 NoneConfirm(空弹窗实例,避免报空指针)。
场景价值

比如输入完成后可能弹出 "保存成功" 弹窗,用例无需硬编码判断:

python 复制代码
# 无需硬编码:if DeleteConfirm.is_show(): ...
confirm = CtrlManager.hasConfirmShow()  # 自动检测弹窗
if not isinstance(confirm, NoneConfirm):
    confirm.click_ok()  # 统一调用弹窗的"确认"方法
3. 参照控件管理:单独管理业务参照控件

负责管理 "参照选择器" 类控件(如 "选择客户""选择商品" 的参照弹窗),逻辑与 "业务控件管理" 类似,核心是 getCanZhao 方法。

方法名 作用 核心逻辑
addCanZhao(cls) 向 "参照控件仓库" 注册参照类(如 CustomerCanZhaoGoodsCanZhao 将参照类添加到 __canzhaos 列表。
canzhao_comps() 获取所有已注册的参照类 返回 __canzhaos 列表。
getCanZhao(ctrl_html) 根据 ctrl_html 匹配参照控件 遍历参照类,调用 is_this_ctrl(ctrl_html) 匹配,返回实例。

三、核心设计:装饰器注册 + 单例模式

CtrlManager 能实现 "低耦合、高扩展",关键依赖两个设计技巧:

单例模式就是调用的基类的instance构造实例

文件末尾的 register_comp/register_confirm/register_canzhao装饰器 ,作用是 "让控件类在定义时自动注册到 CtrlManager",无需手动调用 addComp

复制代码
def register_comp(cls):
    """注册组件到CtrlManager"""
    CtrlManager.addComp(cls)
    return cls

例:用装饰器注册控件

python 复制代码
# 以前:定义控件后,需手动调用 CtrlManager.addComp(InputComp)
# 现在:用 @register_comp 装饰器,定义时自动注册
from script.hsy.component.ctrl.CtrlManager import register_comp

@register_comp  # 装饰器:自动将 InputComp 注册到 CtrlManager.__components
class InputComp(InputCtrlBase):
    def is_this_ctrl(self, ctrl_html):
        # 判断是否匹配当前 HTML 特征
        return 'input' in ctrl_html and 'readonly' not in ctrl_html
  • 新增控件时,只需加一行装饰器,无需修改 CtrlManager 或其他调用处;
  • 控件类与 CtrlManager 解耦(控件无需知道 CtrlManager 的存在,只需被装饰即可)。

四、使用流程:从 "注册" 到 "调用" 的完整链路

以 "新增一个'商品选择控件'(GoodsSelectCtrl)" 为例,看 CtrlManager 的完整使用流程:

⭐ 步骤 1:定义控件并注册
python 复制代码
from script.hsy.component.ctrl.CtrlManager import register_comp

@register_comp  # 装饰器自动注册到 CtrlManager
class GoodsSelectCtrl(InputCtrlBase):
    def is_this_ctrl(self, ctrl_html):
        # 定义匹配规则:HTML 中含"goods-select"类,且是下拉控件
        return 'goods-select' in ctrl_html and 'Select-arrow' in ctrl_html

    def input(self, value):
        # 实现商品选择逻辑:点击下拉→输入商品名→选择
        self.find_child(self.dropdown_loc).click()
        self.find_child(self.search_loc).sendKeys(value)
        self.find_child(self.option_loc.format_key(value)).click()
复制代码
def getCtrl(cls, ctrl_html, parent):
    """
    初始化具体控件,设置父组件
    """
    ctrl_list = []
    for comp in cls.components():

        if comp.is_this_ctrl(ctrl_html):
            ctrl_list.append(comp.instance(parent))...最终返回的是html对应所需控件类实例

即return的值为真,则把该类添加到列表。

⭐ 步骤 2:调用控件(通过 CtrlManager

HsyInput.getInputCtrl 中,无需硬编码调用 GoodsSelectCtrl,而是通过 CtrlManager 动态匹配:

python 复制代码
def getInputCtrl(self, parent, ctrl_html):
    # 其他分支...
    elif self.inputType == InputType.参照输入:
        # 让 CtrlManager 自动匹配控件(包括刚注册的 GoodsSelectCtrl)
        return CtrlManager.getCtrl(ctrl_html, parent)
    # 其他分支...
⭐ 步骤 3:框架自动匹配

当页面 HTML 中出现 "商品选择控件" 的特征(goods-select + Select-arrow)时:

  1. CtrlManager.getCtrl 遍历 __components 列表,找到 GoodsSelectCtrl
  2. 调用 GoodsSelectCtrl.is_this_ctrl(ctrl_html),返回 True(匹配);
  3. 返回 GoodsSelectCtrl.instance(parent) 实例,供后续输入操作使用。
相关推荐
ZCollapsar.6 小时前
数据结构 04(线性:双向链表)
c语言·数据结构·学习·算法·链表
学c语言的枫子7 小时前
Ubuntu22.04网络图标消失问题
linux·学习·ubuntu
丑小鸭是白天鹅7 小时前
嵌入式C学习笔记之链表
c语言·笔记·学习
killer Curry7 小时前
B站 XMCVE Pwn入门课程学习笔记(8)
笔记·学习
楼田莉子7 小时前
前端学习——CSS
前端·css·学习
丁满与彭彭7 小时前
嵌入式学习笔记--LINUX系统编程--DAY03进程控制
linux·笔记·学习
忆萧7 小时前
FFMPEG学习任务
学习·ffmpeg
序属秋秋秋7 小时前
《C++进阶之STL》【红黑树】
开发语言·数据结构·c++·笔记·学习·stl
YoungUpUp9 小时前
【MD文本编辑器Typora】实用工具推荐之——轻量级 Markdown 编辑器Typora下载安装使用教程 办公学习神器
学习·typora·markdown·文档编辑器·markdown编辑器·md文本编辑器·实用办公软件