Files
Any2MIF/core/batch_manager.py
2025-03-07 15:32:58 +08:00

144 lines
4.8 KiB
Python

#!/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()