File size: 8,945 Bytes
eed23a7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
"""
事件处理器管理类
统一管理和绑定UI组件的事件处理逻辑
"""
from typing import Any, Dict, List, Callable
import gradio as gr
class EventManager:
"""事件管理器
负责统一管理和绑定UI组件的事件处理逻辑
"""
def __init__(self):
"""初始化事件管理器"""
self.registered_events: List[Dict[str, Any]] = []
self.event_handlers: Dict[str, Callable] = {}
def register_controller_events(self, controller) -> None:
"""注册控制器的事件
Args:
controller: Tab控制器实例
"""
# 获取控制器的事件配置
events = controller.setup_events()
handlers = controller.get_event_handlers()
# 注册事件处理函数
for handler_name, handler_func in handlers.items():
self.event_handlers[f"{controller.name}_{handler_name}"] = handler_func
# 保存事件配置
for event_config in events:
event_config['controller'] = controller
event_config['handler_key'] = f"{controller.name}_{event_config['handler']}"
self.registered_events.append(event_config)
def bind_all_events(self) -> None:
"""绑定所有已注册的事件"""
for event_config in self.registered_events:
self._bind_single_event(event_config)
def _bind_single_event(self, event_config: Dict[str, Any]) -> None:
"""绑定单个事件
Args:
event_config: 事件配置字典
"""
try:
controller = event_config['controller']
component_name = event_config['component']
event_type = event_config['event']
handler_key = event_config['handler_key']
inputs = event_config.get('inputs', [])
outputs = event_config.get('outputs', [])
# 获取组件对象
component = controller.get_component(component_name)
if component is None:
print(f"⚠️ 警告: 找不到组件 {component_name} 在控制器 {controller.name}")
return
# 获取事件处理函数
handler_func = self.event_handlers.get(handler_key)
if handler_func is None:
print(f"⚠️ 警告: 找不到处理函数 {handler_key}")
return
# 解析输入输出组件
input_components = self._resolve_components(controller, inputs)
output_components = self._resolve_components(controller, outputs)
# 绑定事件
if event_type == "upload":
component.upload(
fn=handler_func,
inputs=input_components,
outputs=output_components
)
elif event_type == "clear":
component.clear(
fn=handler_func,
inputs=input_components,
outputs=output_components
)
elif event_type == "change":
component.change(
fn=handler_func,
inputs=input_components,
outputs=output_components
)
elif event_type == "click":
component.click(
fn=handler_func,
inputs=input_components,
outputs=output_components
)
elif event_type == "submit":
component.submit(
fn=handler_func,
inputs=input_components,
outputs=output_components
)
else:
print(f"⚠️ 警告: 不支持的事件类型 {event_type}")
except Exception as e:
print(f"❌ 绑定事件失败: {e}")
def _resolve_components(self, controller, component_names: List[str]) -> List[Any]:
"""解析组件名称列表为组件对象列表
Args:
controller: 控制器实例
component_names: 组件名称列表
Returns:
组件对象列表
"""
components = []
for name in component_names:
component = controller.get_component(name)
if component is not None:
components.append(component)
else:
# 尝试从全局组件注册表查找(用于跨Tab的组件引用)
global_component = self._find_global_component(name)
if global_component is not None:
components.append(global_component)
else:
print(f"⚠️ 警告: 找不到组件 {name}")
return components
def _find_global_component(self, component_name: str) -> Any:
"""从全局组件注册表查找组件
Args:
component_name: 组件名称
Returns:
组件对象,如果找不到则返回None
"""
# 遍历所有注册的控制器查找组件
for event_config in self.registered_events:
controller = event_config['controller']
component = controller.get_component(component_name)
if component is not None:
return component
return None
def get_handler_count(self) -> int:
"""获取已注册的事件处理器数量
Returns:
事件处理器数量
"""
return len(self.event_handlers)
def get_event_count(self) -> int:
"""获取已注册的事件数量
Returns:
事件数量
"""
return len(self.registered_events)
def print_summary(self) -> None:
"""打印事件管理器摘要信息"""
print(f"📋 事件管理器摘要:")
print(f" - 已注册事件处理器: {self.get_handler_count()} 个")
print(f" - 已注册事件绑定: {self.get_event_count()} 个")
for event_config in self.registered_events:
controller_name = event_config['controller'].name
component_name = event_config['component']
event_type = event_config['event']
handler_name = event_config['handler']
print(f" - {controller_name}.{component_name}.{event_type} -> {handler_name}")
class CrossTabEventManager:
"""跨Tab事件管理器
专门处理需要跨Tab组件交互的事件绑定
"""
def __init__(self, event_manager: EventManager):
"""初始化跨Tab事件管理器
Args:
event_manager: 主事件管理器实例
"""
self.event_manager = event_manager
self.cross_tab_bindings: List[Dict[str, Any]] = []
def register_cross_tab_binding(self,
source_controller,
source_component: str,
target_controller,
target_component: str,
event_type: str = "change") -> None:
"""注册跨Tab组件绑定
Args:
source_controller: 源控制器
source_component: 源组件名称
target_controller: 目标控制器
target_component: 目标组件名称
event_type: 事件类型
"""
binding = {
'source_controller': source_controller,
'source_component': source_component,
'target_controller': target_controller,
'target_component': target_component,
'event_type': event_type
}
self.cross_tab_bindings.append(binding)
def setup_cross_tab_events(self) -> None:
"""设置所有跨Tab事件绑定"""
for binding in self.cross_tab_bindings:
self._setup_single_cross_tab_event(binding)
def _setup_single_cross_tab_event(self, binding: Dict[str, Any]) -> None:
"""设置单个跨Tab事件绑定
Args:
binding: 绑定配置字典
"""
try:
source_comp = binding['source_controller'].get_component(binding['source_component'])
target_comp = binding['target_controller'].get_component(binding['target_component'])
if source_comp is None or target_comp is None:
print(f"⚠️ 警告: 跨Tab绑定失败,组件不存在")
return
# 设置简单的更新绑定(这里可以根据需要扩展)
def update_target(*args):
return args[0] if args else ""
if binding['event_type'] == "change":
source_comp.change(
fn=update_target,
inputs=[source_comp],
outputs=[target_comp]
)
except Exception as e:
print(f"❌ 跨Tab事件绑定失败: {e}") |