""" 拖拽检测器基类 定义所有平台拖拽检测器的通用接口。 """ import os import platform from abc import ABC, abstractmethod from typing import List, Optional, Callable import threading import queue import time class BaseDragDetector(ABC): """拖拽检测器基类""" def __init__(self, supported_formats: List[str] = None): """ 初始化拖拽检测器 Args: supported_formats: 支持的文件格式列表,如 ['.gltf', '.glb', '.fbx'] """ self.supported_formats = supported_formats or ['.gltf', '.glb', '.fbx', '.bam', '.egg', '.obj'] self.is_running = False self.monitor_thread = None self.file_queue = queue.Queue() self.drop_callback: Optional[Callable[[List[str]], None]] = None def set_drop_callback(self, callback: Callable[[List[str]], None]): """ 设置文件拖拽回调函数 Args: callback: 接收文件路径列表的回调函数 """ self.drop_callback = callback def start_monitoring(self): """开始监控拖拽事件""" if not self.is_running: self.is_running = True self.monitor_thread = threading.Thread(target=self._monitor_loop, daemon=True) self.monitor_thread.start() def stop_monitoring(self): """停止监控拖拽事件""" self.is_running = False if self.monitor_thread: self.monitor_thread.join(timeout=1.0) def get_dropped_files(self) -> List[str]: """获取拖拽的文件列表""" files = [] while not self.file_queue.empty(): try: files.append(self.file_queue.get_nowait()) except queue.Empty: break return files def add_dropped_file(self, file_path: str): """ 添加拖拽的文件路径 Args: file_path: 拖拽的文件路径 """ if self._is_supported_format(file_path): self.file_queue.put(file_path) if self.drop_callback: self.drop_callback([file_path]) def _is_supported_format(self, file_path: str) -> bool: """检查文件格式是否支持""" _, ext = os.path.splitext(file_path.lower()) return ext in self.supported_formats @abstractmethod def _monitor_loop(self): """监控循环,由子类实现""" pass @abstractmethod def is_supported(self) -> bool: """检查当前平台是否支持此检测器""" pass class DragDetectorFactory: """拖拽检测器工厂类""" @staticmethod def create_detector(supported_formats: List[str] = None) -> BaseDragDetector: """ 根据当前平台创建合适的拖拽检测器 Args: supported_formats: 支持的文件格式列表 Returns: 适合当前平台的拖拽检测器实例 """ system = platform.system().lower() if system == 'windows': from .windows_detector import WindowsDragDetector return WindowsDragDetector(supported_formats) elif system == 'linux': from .linux_detector import LinuxDragDetector return LinuxDragDetector(supported_formats) elif system == 'darwin': # macOS from .macos_detector import MacOSDragDetector return MacOSDragDetector(supported_formats) else: # 降级到基础检测器 from .fallback_detector import FallbackDragDetector return FallbackDragDetector(supported_formats)