Python实例题:基于 Python 的简单文件管理器

目录

Python实例题

题目

要求:

解题思路:

代码实现:

Python实例题

题目

基于 Python 的简单文件管理器

要求

  • 使用 Python 构建一个简单的文件管理器,支持以下功能:
    • 浏览文件和目录
    • 创建、删除、重命名文件和目录
    • 复制、移动文件和目录
    • 查看文件属性和内容
    • 搜索文件和目录
  • 使用 tkinter 构建图形用户界面。
  • 支持基本的文件操作权限检查。

解题思路

  • 使用 os 和 shutil 模块进行文件操作。
  • 通过 tkinter 构建用户友好的界面。
  • 实现文件列表的树形视图和详细视图。
  • 添加右键菜单和快捷键支持。

代码实现

import os
import shutil
import tkinter as tk
from tkinter import ttk, filedialog, messagebox, simpledialog
import datetime
import threading
import time
from pathlib import Path

class FileManager:
    def __init__(self, root):
        self.root = root
        self.root.title("文件管理器")
        self.root.geometry("1000x600")
        
        # 设置字体以支持中文显示
        self.default_font = ('SimHei', 10)
        self.root.option_add("*Font", self.default_font)
        
        # 当前路径
        self.current_path = os.getcwd()
        
        # 创建主界面
        self.create_widgets()
        
        # 加载初始目录
        self.load_directory(self.current_path)
    
    def create_widgets(self):
        """创建界面组件"""
        # 创建主框架
        main_frame = ttk.Frame(self.root)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        
        # 创建顶部导航栏
        nav_frame = ttk.Frame(main_frame)
        nav_frame.pack(fill=tk.X, padx=5, pady=5)
        
        # 返回上级目录按钮
        ttk.Button(nav_frame, text="上级目录", command=self.go_up).pack(side=tk.LEFT, padx=5)
        
        # 刷新按钮
        ttk.Button(nav_frame, text="刷新", command=lambda: self.load_directory(self.current_path)).pack(side=tk.LEFT, padx=5)
        
        # 地址栏
        self.path_var = tk.StringVar()
        self.path_entry = ttk.Entry(nav_frame, textvariable=self.path_var, width=80)
        self.path_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)
        self.path_entry.bind("", lambda event: self.navigate_to_path())
        
        # 转到按钮
        ttk.Button(nav_frame, text="转到", command=self.navigate_to_path).pack(side=tk.LEFT, padx=5)
        
        # 创建左右分割的主区域
        paned_window = ttk.PanedWindow(main_frame, orient=tk.HORIZONTAL)
        paned_window.pack(fill=tk.BOTH, expand=True, pady=5)
        
        # 左侧树形视图(目录结构)
        self.tree_frame = ttk.Frame(paned_window)
        paned_window.add(self.tree_frame, weight=1)
        
        # 右侧文件列表视图
        self.list_frame = ttk.Frame(paned_window)
        paned_window.add(self.list_frame, weight=3)
        
        # 创建树形视图
        self.create_tree_view()
        
        # 创建文件列表视图
        self.create_file_list_view()
        
        # 创建底部状态栏
        self.status_var = tk.StringVar()
        self.status_var.set(f"当前路径: {self.current_path}")
        status_bar = ttk.Label(self.root, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W)
        status_bar.pack(side=tk.BOTTOM, fill=tk.X)
    
    def create_tree_view(self):
        """创建目录树视图"""
        # 创建滚动条
        tree_scroll = ttk.Scrollbar(self.tree_frame)
        tree_scroll.pack(side=tk.RIGHT, fill=tk.Y)
        
        # 创建树形视图
        self.tree = ttk.Treeview(self.tree_frame, yscrollcommand=tree_scroll.set)
        self.tree.pack(fill=tk.BOTH, expand=True)
        tree_scroll.config(command=self.tree.yview)
        
        # 设置列
        self.tree["columns"] = ("path")
        self.tree.column("#0", width=200, minwidth=200)
        self.tree.column("path", width=0, stretch=tk.NO)
        
        # 设置标题
        self.tree.heading("#0", text="目录结构", anchor=tk.W)
        
        # 绑定事件
        self.tree.bind("", self.on_tree_select)
        
        # 加载根目录
        self.load_tree()
    
    def load_tree(self):
        """加载目录树"""
        # 清空树
        for item in self.tree.get_children():
            self.tree.delete(item)
        
        # 获取系统根目录
        if os.name == 'nt':  # Windows系统
            roots = [f"{drive}:\\" for drive in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" if os.path.exists(f"{drive}:\\")]
        else:  # Linux/Mac系统
            roots = ["/"]
        
        # 添加根目录到树
        for root in roots:
            self.tree.insert("", tk.END, text=root, values=(root,))
            self.load_tree_children(root, "")
    
    def load_tree_children(self, path, parent_id):
        """递归加载目录树的子目录"""
        try:
            for item in os.listdir(path):
                item_path = os.path.join(path, item)
                if os.path.isdir(item_path):
                    item_id = self.tree.insert(parent_id, tk.END, text=item, values=(item_path,))
                    # 添加子目录标记
                    self.tree.insert(item_id, tk.END)
    
        except PermissionError:
            pass
    
    def on_tree_select(self, event):
        """处理树节点选择事件"""
        selected_item = self.tree.selection()
        if not selected_item:
            return
        
        item = selected_item[0]
        path = self.tree.item(item, "values")[0]
        
        # 如果该节点有子目录且未加载,则加载子目录
        if self.tree.get_children(item) and self.tree.item(self.tree.get_children(item)[0], "text") == '':
            self.tree.delete(self.tree.get_children(item))
            self.load_tree_children(path, item)
        
        # 加载选中的目录
        self.load_directory(path)
    
    def create_file_list_view(self):
        """创建文件列表视图"""
        # 创建顶部工具栏
        toolbar = ttk.Frame(self.list_frame)
        toolbar.pack(fill=tk.X, padx=5, pady=5)
        
        # 新建文件夹按钮
        ttk.Button(toolbar, text="新建文件夹", command=self.create_directory).pack(side=tk.LEFT, padx=5)
        
        # 删除按钮
        ttk.Button(toolbar, text="删除", command=self.delete_selected).pack(side=tk.LEFT, padx=5)
        
        # 重命名按钮
        ttk.Button(toolbar, text="重命名", command=self.rename_selected).pack(side=tk.LEFT, padx=5)
        
        # 复制按钮
        ttk.Button(toolbar, text="复制", command=self.copy_selected).pack(side=tk.LEFT, padx=5)
        
        # 移动按钮
        ttk.Button(toolbar, text="移动", command=self.move_selected).pack(side=tk.LEFT, padx=5)
        
        # 搜索框
        search_frame = ttk.Frame(toolbar)
        search_frame.pack(side=tk.RIGHT, padx=5)
        
        ttk.Label(search_frame, text="搜索:").pack(side=tk.LEFT, padx=5)
        self.search_var = tk.StringVar()
        search_entry = ttk.Entry(search_frame, textvariable=self.search_var, width=20)
        search_entry.pack(side=tk.LEFT, padx=5)
        search_entry.bind("", lambda event: self.search_files())
        
        ttk.Button(search_frame, text="搜索", command=self.search_files).pack(side=tk.LEFT, padx=5)
        
        # 创建滚动条
        list_scroll = ttk.Scrollbar(self.list_frame)
        list_scroll.pack(side=tk.RIGHT, fill=tk.Y)
        
        # 创建文件列表
        columns = ("name", "type", "size", "modified", "path")
        self.file_list = ttk.Treeview(self.list_frame, columns=columns, show="headings", yscrollcommand=list_scroll.set)
        self.file_list.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        list_scroll.config(command=self.file_list.yview)
        
        # 设置列宽和标题
        self.file_list.column("name", width=250, anchor=tk.W)
        self.file_list.column("type", width=100, anchor=tk.CENTER)
        self.file_list.column("size", width=100, anchor=tk.RIGHT)
        self.file_list.column("modified", width=150, anchor=tk.CENTER)
        self.file_list.column("path", width=0, stretch=tk.NO)  # 隐藏路径列
        
        self.file_list.heading("name", text="名称")
        self.file_list.heading("type", text="类型")
        self.file_list.heading("size", text="大小")
        self.file_list.heading("modified", text="修改日期")
        
        # 绑定事件
        self.file_list.bind("", self.on_double_click)
        self.file_list.bind("", self.on_right_click)
        
        # 创建右键菜单
        self.create_context_menu()
    
    def create_context_menu(self):
        """创建右键菜单"""
        self.context_menu = tk.Menu(self.root, tearoff=0)
        self.context_menu.add_command(label="打开", command=self.open_selected)
        self.context_menu.add_separator()
        self.context_menu.add_command(label="新建文件夹", command=self.create_directory)
        self.context_menu.add_separator()
        self.context_menu.add_command(label="复制", command=self.copy_selected)
        self.context_menu.add_command(label="移动", command=self.move_selected)
        self.context_menu.add_separator()
        self.context_menu.add_command(label="重命名", command=self.rename_selected)
        self.context_menu.add_command(label="删除", command=self.delete_selected)
        self.context_menu.add_separator()
        self.context_menu.add_command(label="查看属性", command=self.show_properties)
    
    def on_right_click(self, event):
        """处理右键点击事件"""
        # 选择点击的项
        item = self.file_list.identify_row(event.y)
        if item:
            self.file_list.selection_set(item)
            self.context_menu.post(event.x_root, event.y_root)
    
    def load_directory(self, path):
        """加载目录内容"""
        try:
            # 更新当前路径
            self.current_path = path
            self.path_var.set(path)
            
            # 清空文件列表
            for item in self.file_list.get_children():
                self.file_list.delete(item)
            
            # 获取目录内容
            items = os.listdir(path)
            
            # 先添加目录,再添加文件(按名称排序)
            directories = []
            files = []
            
            for item in items:
                item_path = os.path.join(path, item)
                if os.path.isdir(item_path):
                    directories.append(item)
                else:
                    files.append(item)
            
            # 排序
            directories.sort(key=str.lower)
            files.sort(key=str.lower)
            
            # 添加到列表
            for item in directories + files:
                item_path = os.path.join(path, item)
                try:
                    # 获取文件信息
                    stat = os.stat(item_path)
                    modified_time = datetime.datetime.fromtimestamp(stat.st_mtime).strftime('%Y-%m-%d %H:%M')
                    
                    if os.path.isdir(item_path):
                        item_type = "文件夹"
                        size = "-"
                    else:
                        item_type = "文件"
                        size = self.format_size(stat.st_size)
                    
                    # 添加到列表
                    self.file_list.insert("", tk.END, values=(item, item_type, size, modified_time, item_path))
                except (PermissionError, OSError):
                    continue
            
            # 更新状态栏
            self.status_var.set(f"当前路径: {path} | 文件夹: {len(directories)} | 文件: {len(files)}")
            
            # 在树形视图中高亮显示当前目录
            self.highlight_current_directory_in_tree()
            
        except (PermissionError, FileNotFoundError) as e:
            messagebox.showerror("错误", f"无法访问该目录: {e}")
            # 尝试返回上级目录
            if os.path.dirname(path) != path:
                self.load_directory(os.path.dirname(path))
    
    def highlight_current_directory_in_tree(self):
        """在树形视图中高亮显示当前目录"""
        # 遍历树形视图,查找当前路径
        def find_item(parent, path):
            for item in self.tree.get_children(parent):
                item_path = self.tree.item(item, "values")[0]
                if item_path == path:
                    return item
                if path.startswith(item_path) and os.path.isdir(item_path):
                    # 如果该节点有子目录且未加载,则加载子目录
                    if self.tree.get_children(item) and self.tree.item(self.tree.get_children(item)[0], "text") == '':
                        self.tree.delete(self.tree.get_children(item))
                        self.load_tree_children(item_path, item)
                    
                    # 递归查找子节点
                    result = find_item(item, path)
                    if result:
                        return result
            return None
        
        # 查找并选中当前路径
        item = find_item("", self.current_path)
        if item:
            self.tree.selection_set(item)
            self.tree.see(item)
    
    def format_size(self, size_bytes):
        """格式化文件大小"""
        if size_bytes < 1024:
            return f"{size_bytes} B"
        elif size_bytes < 1024 * 1024:
            return f"{size_bytes/1024:.2f} KB"
        elif size_bytes < 1024 * 1024 * 1024:
            return f"{size_bytes/(1024*1024):.2f} MB"
        else:
            return f"{size_bytes/(1024*1024*1024):.2f} GB"
    
    def go_up(self):
        """返回上级目录"""
        parent_path = os.path.dirname(self.current_path)
        if parent_path != self.current_path:  # 避免在根目录时出错
            self.load_directory(parent_path)
    
    def navigate_to_path(self):
        """导航到地址栏中的路径"""
        path = self.path_var.get()
        if os.path.exists(path) and os.path.isdir(path):
            self.load_directory(path)
        else:
            messagebox.showerror("错误", f"路径不存在: {path}")
    
    def on_double_click(self, event):
        """处理双击事件"""
        selected_items = self.file_list.selection()
        if not selected_items:
            return
        
        item = selected_items[0]
        item_path = self.file_list.item(item, "values")[4]
        
        if os.path.isdir(item_path):
            # 如果是目录,则打开
            self.load_directory(item_path)
        else:
            # 如果是文件,则尝试打开
            self.open_selected()
    
    def open_selected(self):
        """打开选中的文件或目录"""
        selected_items = self.file_list.selection()
        if not selected_items:
            return
        
        item = selected_items[0]
        item_path = self.file_list.item(item, "values")[4]
        
        try:
            if os.path.isdir(item_path):
                self.load_directory(item_path)
            else:
                # 尝试打开文件
                if os.name == 'nt':  # Windows
                    os.startfile(item_path)
                else:  # Linux/Mac
                    os.system(f'xdg-open "{item_path}"')
        except Exception as e:
            messagebox.showerror("错误", f"无法打开: {e}")
    
    def create_directory(self):
        """创建新目录"""
        dir_name = simpledialog.askstring("新建文件夹", "输入文件夹名称:", parent=self.root)
        if not dir_name:
            return
        
        new_dir_path = os.path.join(self.current_path, dir_name)
        
        try:
            if not os.path.exists(new_dir_path):
                os.makedirs(new_dir_path)
                self.load_directory(self.current_path)
                messagebox.showinfo("成功", f"文件夹 '{dir_name}' 已创建")
            else:
                messagebox.showerror("错误", f"文件夹 '{dir_name}' 已存在")
        except Exception as e:
            messagebox.showerror("错误", f"无法创建文件夹: {e}")
    
    def delete_selected(self):
        """删除选中的文件或目录"""
        selected_items = self.file_list.selection()
        if not selected_items:
            return
        
        # 确认删除
        count = len(selected_items)
        message = f"确定要删除选中的 {count} 个项目吗?此操作不可撤销!"
        if messagebox.askyesno("确认删除", message):
            for item in selected_items:
                item_path = self.file_list.item(item, "values")[4]
                
                try:
                    if os.path.isdir(item_path):
                        # 删除目录(递归)
                        shutil.rmtree(item_path)
                    else:
                        # 删除文件
                        os.remove(item_path)
                except Exception as e:
                    messagebox.showerror("错误", f"无法删除 '{os.path.basename(item_path)}': {e}")
            
            # 刷新目录
            self.load_directory(self.current_path)
    
    def rename_selected(self):
        """重命名选中的文件或目录"""
        selected_items = self.file_list.selection()
        if not selected_items or len(selected_items) > 1:
            return
        
        item = selected_items[0]
        old_name = self.file_list.item(item, "values")[0]
        old_path = self.file_list.item(item, "values")[4]
        
        new_name = simpledialog.askstring("重命名", "输入新名称:", initialvalue=old_name, parent=self.root)
        if not new_name or new_name == old_name:
            return
        
        new_path = os.path.join(self.current_path, new_name)
        
        try:
            if not os.path.exists(new_path):
                os.rename(old_path, new_path)
                self.load_directory(self.current_path)
                messagebox.showinfo("成功", f"'{old_name}' 已重命名为 '{new_name}'")
            else:
                messagebox.showerror("错误", f"'{new_name}' 已存在")
        except Exception as e:
            messagebox.showerror("错误", f"无法重命名: {e}")
    
    def copy_selected(self):
        """复制选中的文件或目录"""
        selected_items = self.file_list.selection()
        if not selected_items:
            return
        
        # 记录选中的项目路径
        self.copied_items = [self.file_list.item(item, "values")[4] for item in selected_items]
        self.copy_operation = "copy"
        
        messagebox.showinfo("复制", f"已复制 {len(selected_items)} 个项目")
    
    def move_selected(self):
        """移动选中的文件或目录"""
        selected_items = self.file_list.selection()
        if not selected_items:
            return
        
        # 记录选中的项目路径
        self.copied_items = [self.file_list.item(item, "values")[4] for item in selected_items]
        self.copy_operation = "move"
        
        messagebox.showinfo("移动", f"已剪切 {len(selected_items)} 个项目")
    
    def paste(self):
        """粘贴复制或移动的项目"""
        if not hasattr(self, 'copied_items') or not self.copied_items:
            return
        
        for item_path in self.copied_items:
            item_name = os.path.basename(item_path)
            dest_path = os.path.join(self.current_path, item_name)
            
            # 检查目标是否已存在
            if os.path.exists(dest_path):
                # 如果已存在,添加数字后缀
                base_name, ext = os.path.splitext(item_name)
                count = 1
                while os.path.exists(dest_path):
                    new_name = f"{base_name} ({count}){ext}"
                    dest_path = os.path.join(self.current_path, new_name)
                    count += 1
            
            try:
                if self.copy_operation == "copy":
                    if os.path.isdir(item_path):
                        # 复制目录
                        shutil.copytree(item_path, dest_path)
                    else:
                        # 复制文件
                        shutil.copy2(item_path, dest_path)
                else:
                    # 移动
                    shutil.move(item_path, dest_path)
            except Exception as e:
                messagebox.showerror("错误", f"无法{self.copy_operation}: {e}")
        
        # 刷新目录
        self.load_directory(self.current_path)
        
        # 清除复制/移动的项目
        if self.copy_operation == "move":
            self.copied_items = []
    
    def show_properties(self):
        """显示选中项目的属性"""
        selected_items = self.file_list.selection()
        if not selected_items or len(selected_items) > 1:
            return
        
        item = selected_items[0]
        item_path = self.file_list.item(item, "values")[4]
        
        try:
            stat = os.stat(item_path)
            
            # 创建属性窗口
            properties_window = tk.Toplevel(self.root)
            properties_window.title(f"{os.path.basename(item_path)} 的属性")
            properties_window.geometry("400x300")
            properties_window.resizable(False, False)
            
            # 创建属性信息
            frame = ttk.Frame(properties_window, padding=10)
            frame.pack(fill=tk.BOTH, expand=True)
            
            # 基本信息
            ttk.Label(frame, text=f"名称: {os.path.basename(item_path)}").grid(row=0, column=0, sticky=tk.W, pady=5)
            ttk.Label(frame, text=f"类型: {'文件夹' if os.path.isdir(item_path) else '文件'}").grid(row=1, column=0, sticky=tk.W, pady=5)
            ttk.Label(frame, text=f"位置: {os.path.dirname(item_path)}").grid(row=2, column=0, sticky=tk.W, pady=5)
            
            if not os.path.isdir(item_path):
                ttk.Label(frame, text=f"大小: {self.format_size(stat.st_size)}").grid(row=3, column=0, sticky=tk.W, pady=5)
            
            ttk.Label(frame, text=f"创建时间: {datetime.datetime.fromtimestamp(stat.st_ctime).strftime('%Y-%m-%d %H:%M:%S')}").grid(row=4, column=0, sticky=tk.W, pady=5)
            ttk.Label(frame, text=f"修改时间: {datetime.datetime.fromtimestamp(stat.st_mtime).strftime('%Y-%m-%d %H:%M:%S')}").grid(row=5, column=0, sticky=tk.W, pady=5)
            ttk.Label(frame, text=f"访问时间: {datetime.datetime.fromtimestamp(stat.st_atime).strftime('%Y-%m-%d %H:%M:%S')}").grid(row=6, column=0, sticky=tk.W, pady=5)
            
            # 权限信息
            ttk.Label(frame, text="").grid(row=7, column=0, pady=10)
            ttk.Label(frame, text="权限:").grid(row=8, column=0, sticky=tk.W)
            
            perms = []
            if os.access(item_path, os.R_OK):
                perms.append("读取")
            if os.access(item_path, os.W_OK):
                perms.append("写入")
            if os.access(item_path, os.X_OK):
                perms.append("执行")
            
            ttk.Label(frame, text=", ".join(perms) if perms else "无权限").grid(row=9, column=0, sticky=tk.W, pady=5)
            
            # 关闭按钮
            ttk.Button(frame, text="确定", command=properties_window.destroy).grid(row=10, column=0, pady=20)
            
        except Exception as e:
            messagebox.showerror("错误", f"无法获取属性: {e}")
    
    def search_files(self):
        """搜索文件和目录"""
        search_text = self.search_var.get().strip().lower()
        if not search_text:
            # 如果搜索文本为空,则重新加载当前目录
            self.load_directory(self.current_path)
            return
        
        # 创建搜索结果窗口
        search_window = tk.Toplevel(self.root)
        search_window.title(f"搜索: {search_text}")
        search_window.geometry("800x500")
        
        # 创建搜索结果列表
        columns = ("name", "type", "size", "modified", "path")
        search_results = ttk.Treeview(search_window, columns=columns, show="headings")
        search_results.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        
        # 设置列宽和标题
        search_results.column("name", width=250, anchor=tk.W)
        search_results.column("type", width=100, anchor=tk.CENTER)
        search_results.column("size", width=100, anchor=tk.RIGHT)
        search_results.column("modified", width=150, anchor=tk.CENTER)
        search_results.column("path", width=0, stretch=tk.NO)  # 隐藏路径列
        
        search_results.heading("name", text="名称")
        search_results.heading("type", text="类型")
        search_results.heading("size", text="大小")
        search_results.heading("modified", text="修改日期")
        
        # 绑定双击事件
        search_results.bind("", lambda event: self.on_search_result_double_click(event, search_results))
        
        # 创建状态栏
        status_var = tk.StringVar()
        status_var.set("正在搜索...")
        status_bar = ttk.Label(search_window, textvariable=status_var, relief=tk.SUNKEN, anchor=tk.W)
        status_bar.pack(side=tk.BOTTOM, fill=tk.X)
        
        # 在单独的线程中执行搜索,避免UI卡顿
        def perform_search():
            results_count = 0
            start_time = time.time()
            
            try:
                for root, dirs, files in os.walk(self.current_path):
                    # 搜索目录
                    for dir_name in dirs:
                        if search_text in dir_name.lower():
                            dir_path = os.path.join(root, dir_name)
                            try:
                                stat = os.stat(dir_path)
                                modified_time = datetime.datetime.fromtimestamp(stat.st_mtime).strftime('%Y-%m-%d %H:%M')
                                search_results.insert("", tk.END, values=(
                                    dir_name, "文件夹", "-", modified_time, dir_path
                                ))
                                results_count += 1
                            except (PermissionError, OSError):
                                continue
                    
                    # 搜索文件
                    for file_name in files:
                        if search_text in file_name.lower():
                            file_path = os.path.join(root, file_name)
                            try:
                                stat = os.stat(file_path)
                                modified_time = datetime.datetime.fromtimestamp(stat.st_mtime).strftime('%Y-%m-%d %H:%M')
                                size = self.format_size(stat.st_size)
                                search_results.insert("", tk.END, values=(
                                    file_name, "文件", size, modified_time, file_path
                                ))
                                results_count += 1
                            except (PermissionError, OSError):
                                continue
            
            except Exception as e:
                status_var.set(f"搜索出错: {e}")
            
            end_time = time.time()
            status_var.set(f"搜索完成,找到 {results_count} 个结果,耗时 {end_time - start_time:.2f} 秒")
        
        # 启动搜索线程
        search_thread = threading.Thread(target=perform_search)
        search_thread.daemon = True
        search_thread.start()
    
    def on_search_result_double_click(self, event, treeview):
        """处理搜索结果双击事件"""
        selected_items = treeview.selection()
        if not selected_items:
            return
        
        item = selected_items[0]
        item_path = treeview.item(item, "values")[4]
        
        if os.path.isdir(item_path):
            # 如果是目录,则关闭搜索窗口并打开该目录
            event.widget.master.destroy()
            self.load_directory(item_path)
        else:
            # 如果是文件,则尝试打开
            try:
                if os.name == 'nt':  # Windows
                    os.startfile(item_path)
                else:  # Linux/Mac
                    os.system(f'xdg-open "{item_path}"')
            except Exception as e:
                messagebox.showerror("错误", f"无法打开: {e}")

if __name__ == "__main__":
    root = tk.Tk()
    app = FileManager(root)
    root.mainloop()

你可能感兴趣的:(实例,python,开发语言,前端)