#!/usr/bin/env python # -*- coding: utf-8 -*- # Copyright (c) 2025 Any2MIF Project # All rights reserved. """ Any2MIF - 批量队列管理器 负责管理批量转换任务 """ import os import threading import queue from PyQt6.QtCore import QObject, pyqtSignal class BatchManager(QObject): """批量队列管理器""" # 自定义信号 progress_updated = pyqtSignal(int, int, str) # 进度更新信号 (当前, 总数, 文件名) conversion_completed = pyqtSignal(int, int) # 转换完成信号 (成功数, 失败数) def __init__(self, converter): """ 初始化批量队列管理器 参数: converter: MIF转换器实例 """ super().__init__() self.converter = converter self.task_queue = queue.Queue() self.is_running = False self.worker_thread = None self.success_count = 0 self.fail_count = 0 def start_batch(self, files, output_dir, params, processed_image=None): """ 启动批量转换 参数: files (list): 文件路径列表 output_dir (str): 输出目录 params (dict): 转换参数 processed_image (PIL.Image, optional): 处理后的图像,如果提供则用于所有图像文件 """ # 如果已经在运行,则返回 if self.is_running: return # 重置计数器 self.success_count = 0 self.fail_count = 0 # 清空队列 while not self.task_queue.empty(): self.task_queue.get() # 添加任务到队列 for file_path in files: output_file = os.path.join( output_dir, f"{os.path.splitext(os.path.basename(file_path))[0]}.mif" ) # 如果有处理后的图像,并且是图像文件,则标记为使用处理后的图像 use_processed = processed_image is not None and file_path.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp', '.gif', '.tiff')) self.task_queue.put((file_path, output_file, params, use_processed, processed_image)) # 设置运行标志 self.is_running = True # 创建并启动工作线程 self.worker_thread = threading.Thread(target=self._worker) self.worker_thread.daemon = True self.worker_thread.start() def _worker(self): """工作线程函数""" total_tasks = self.task_queue.qsize() current_task = 0 try: while not self.task_queue.empty(): # 获取任务 file_path, output_file, params, use_processed, processed_image = self.task_queue.get() current_task += 1 # 发出进度更新信号 self.progress_updated.emit(current_task, total_tasks, os.path.basename(file_path)) try: # 执行转换 if use_processed and processed_image: # 使用处理后的图像直接转换 success = self.converter.convert_from_image(processed_image, output_file, params) else: # 使用文件路径转换 success = self.converter.convert(file_path, output_file, params) # 更新计数器 if success: self.success_count += 1 else: self.fail_count += 1 except Exception as e: print(f"转换错误: {str(e)}") self.fail_count += 1 # 标记任务完成 self.task_queue.task_done() finally: # 设置运行标志 self.is_running = False # 发出转换完成信号 self.conversion_completed.emit(self.success_count, self.fail_count) def is_busy(self): """ 检查是否正在处理任务 返回: bool: 是否正在处理任务 """ return self.is_running def get_progress(self): """ 获取当前进度 返回: tuple: (当前任务数, 总任务数, 成功数, 失败数) """ total_tasks = self.task_queue.qsize() + self.success_count + self.fail_count current_task = self.success_count + self.fail_count return (current_task, total_tasks, self.success_count, self.fail_count) def cancel(self): """取消所有任务""" # 清空队列 while not self.task_queue.empty(): self.task_queue.get() self.task_queue.task_done()