#!/usr/bin/env python # -*- coding: utf-8 -*- """ 文件选择器组件 提供文件/目录选择功能的组合组件。 """ import tkinter as tk from tkinter import filedialog, ttk from typing import Optional, Callable class FileSelector(ttk.Frame): """文件选择器组件""" def __init__( self, parent, label_text: str = "", file_type: str = "file", file_types: list = None, initial_dir: str = "", on_change: Optional[Callable] = None ): """ 初始化文件选择器 Args: parent: 父容器 label_text: 标签文本 file_type: 选择类型 ('file' 或 'directory') file_types: 文件类型过滤器,如 [("Excel", "*.xlsx")] initial_dir: 初始目录 on_change: 值改变时的回调函数 """ super().__init__(parent) self.file_type = file_type self.file_types = file_types or [("所有文件", "*.*")] self.initial_dir = initial_dir self.on_change = on_change # 创建标签 if label_text: self.label = ttk.Label(self, text=label_text) self.label.grid(row=0, column=0, sticky="w", padx=(0, 5)) # 创建输入框 self.entry_var = tk.StringVar() self.entry = ttk.Entry(self, textvariable=self.entry_var, width=50) self.entry.grid(row=0, column=1, sticky="ew", padx=5) # 创建浏览按钮 self.browse_button = ttk.Button(self, text="浏览...", command=self._browse) self.browse_button.grid(row=0, column=2, padx=5) # 配置列权重 self.columnconfigure(1, weight=1) def _browse(self) -> None: """打开文件/目录选择对话框""" current_path = self.entry_var.get() or self.initial_dir if self.file_type == "file": path = filedialog.askopenfilename( title="选择文件", initialdir=current_path, filetypes=self.file_types ) else: # directory path = filedialog.askdirectory( title="选择目录", initialdir=current_path ) if path: self.entry_var.set(path) if self.on_change: self.on_change(path) def get(self) -> str: """获取当前选择的路径""" return self.entry_var.get() def set(self, path: str) -> None: """设置路径""" self.entry_var.set(path) def clear(self) -> None: """清空路径""" self.entry_var.set("") def is_empty(self) -> bool: """检查是否为空""" return not self.entry_var.get()