73 lines
2.3 KiB
Python
73 lines
2.3 KiB
Python
import tkinter as tk
|
|
from tkinter import filedialog
|
|
from nicegui import ui, run
|
|
from loguru import logger
|
|
|
|
from ui.core.state import app_state
|
|
|
|
|
|
async def select_folder():
|
|
"""在 Native 模式下弹窗选择文件夹"""
|
|
|
|
def _pick():
|
|
root = tk.Tk()
|
|
root.withdraw()
|
|
root.attributes("-topmost", True)
|
|
path = filedialog.askdirectory()
|
|
root.destroy()
|
|
return path
|
|
|
|
return await run.io_bound(_pick)
|
|
|
|
|
|
async def run_task(func, *args, **kwargs):
|
|
"""通用任务执行器"""
|
|
if app_state.is_running:
|
|
ui.notify("当前有任务正在运行,请稍候...", type="warning")
|
|
return
|
|
|
|
# 1. 状态重置
|
|
app_state.is_running = True
|
|
app_state.stop_event.clear()
|
|
if app_state.progress_bar: app_state.progress_bar.set_value(0)
|
|
if app_state.progress_label: app_state.progress_label.set_text("🚀 正在启动任务...")
|
|
|
|
# 2. 定义进度条回调
|
|
def progress_callback(current, total, task_name="任务"):
|
|
if total <= 0:
|
|
pct = 0
|
|
text = f"{task_name}: 准备中..."
|
|
else:
|
|
pct = current / total
|
|
text = f"{task_name}: {current}/{total} ({int(pct * 100)}%)"
|
|
|
|
# 更新 UI
|
|
if app_state.progress_bar: app_state.progress_bar.set_value(pct)
|
|
if app_state.progress_label: app_state.progress_label.set_text(text)
|
|
|
|
# 3. 组装参数
|
|
kwargs['progress_callback'] = progress_callback
|
|
kwargs['stop_event'] = app_state.stop_event
|
|
|
|
# 4. 执行
|
|
try:
|
|
# 适配器:检查函数是否接受 stop_event
|
|
def _exec():
|
|
try:
|
|
func(*args, **kwargs)
|
|
except TypeError:
|
|
kwargs.pop('stop_event', None)
|
|
func(*args, **kwargs)
|
|
|
|
await run.io_bound(_exec)
|
|
|
|
if app_state.progress_label: app_state.progress_label.set_text("✅ 任务完成")
|
|
ui.notify("任务执行成功!", type="positive")
|
|
|
|
except Exception as e:
|
|
logger.error(f"任务出错: {e}")
|
|
if app_state.progress_label: app_state.progress_label.set_text(f"❌ 错误: {str(e)}")
|
|
ui.notify(f"任务失败: {e}", type="negative")
|
|
finally:
|
|
app_state.is_running = False
|
|
if app_state.progress_bar: app_state.progress_bar.set_value(0) |