🚀 FileMate Pro:基于 Tkinter 的 Python GUI 文件管理器

发布: (2026年1月1日 GMT+8 00:32)
5 min read
原文: Dev.to

I’m happy to translate the article for you, but I’ll need the full text of the post (the content you’d like translated) in order to do so. Could you please paste the article’s body here? Once I have the text, I’ll provide a Simplified‑Chinese translation while preserving the source link, formatting, markdown, and any code blocks unchanged.

📌 Features

  • 使用文件夹和文件图标浏览目录
  • 双击打开文件
  • 创建、删除和重命名文件/文件夹
  • 复制与粘贴功能
  • 暗/亮模式切换
  • 状态栏实时反馈

🖥️ 截图预览

(如果您愿意,可以在此添加 GUI 的截图。)

🛠️ 完整脚本

import sys
import os
import shutil
import tkinter as tk
from tkinter import ttk, messagebox, simpledialog
import sv_ttk

def resource_path(file_name):
    """Get the absolute path to a resource, works for PyInstaller."""
    base_path = getattr(sys, "_MEIPASS", os.path.dirname(os.path.abspath(__file__)))
    return os.path.join(base_path, file_name)

# =========================
# App Setup
# =========================
root = tk.Tk()
root.title("FileMate Pro")
root.geometry("1000x680")
root.minsize(1000, 680)
sv_ttk.set_theme("light")

# =========================
# Globals
# =========================
dark_mode_var = tk.BooleanVar(value=False)
current_path_var = tk.StringVar(value=os.path.expanduser("~"))
status_var = tk.StringVar(value="Ready")
clipboard = None

# =========================
# Helpers
# =========================
def set_status(msg):
    status_var.set(msg)
    root.update_idletasks()

def toggle_theme():
    sv_ttk.set_theme("dark" if dark_mode_var.get() else "light")
    set_status(f"Theme switched to {'Dark' if dark_mode_var.get() else 'Light'} mode")

def refresh_file_list(path=None):
    path = path or current_path_var.get()
    if not os.path.exists(path):
        messagebox.showerror("Error", "Path does not exist!")
        return
    current_path_var.set(path)
    file_listbox.delete(0, tk.END)
    try:
        for item in os.listdir(path):
            full_path = os.path.join(path, item)
            display = "📁 " + item if os.path.isdir(full_path) else "📄 " + item
            file_listbox.insert(tk.END, display)
        set_status(f"Listing files in {path}")
    except PermissionError:
        messagebox.showerror("Error", "Permission denied.")

def open_selected():
    selection = file_listbox.curselection()
    if not selection:
        return
    item_text = file_listbox.get(selection[0])
    item_name = item_text[2:]          # strip the emoji prefix
    path = os.path.join(current_path_var.get(), item_name)
    if os.path.isdir(path):
        refresh_file_list(path)
    else:
        try:
            os.startfile(path)
            set_status(f"Opened {item_name}")
        except Exception as e:
            messagebox.showerror("Error", f"Cannot open file: {e}")

def go_up():
    parent = os.path.dirname(current_path_var.get())
    refresh_file_list(parent)

def create_folder():
    folder_name = simpledialog.askstring("Create Folder", "Enter folder name:")
    if folder_name:
        path = os.path.join(current_path_var.get(), folder_name)
        try:
            os.makedirs(path)
            refresh_file_list()
            set_status(f"Folder '{folder_name}' created")
        except FileExistsError:
            messagebox.showerror("Error", "Folder already exists.")
        except Exception as e:
            messagebox.showerror("Error", str(e))

def delete_item(path=None):
    if not path:
        selection = file_listbox.curselection()
        if not selection:
            return
        item_text = file_listbox.get(selection[0])
        item_name = item_text[2:]
        path = os.path.join(current_path_var.get(), item_name)
    if messagebox.askyesno("Confirm Delete", f"Are you sure you want to delete '{os.path.basename(path)}'?"):
        try:
            if os.path.isdir(path):
                shutil.rmtree(path)
            else:
                os.remove(path)
            refresh_file_list()
            set_status(f"Deleted '{os.path.basename(path)}'")
        except Exception as e:
            messagebox.showerror("Error", str(e))

def rename_item():
    selection = file_listbox.curselection()
    if not selection:
        return
    item_text = file_listbox.get(selection[0])
    old_name = item_text[2:]
    old_path = os.path.join(current_path_var.get(), old_name)
    new_name = simpledialog.askstring("Rename", f"Enter new name for '{old_name}':")
    if new_name:
        new_path = os.path.join(current_path_var.get(), new_name)
        try:
            os.re

name(old_path, new_path) refresh_file_list() set_status(f”Renamed ‘{old_name}’ to ‘{new_name}’”) except Exception as e: messagebox.showerror(“Error”, str(e))

def copy_item(): global clipboard selection = file_listbox.curselection() if not selection: return item_text = file_listbox.get(selection[0]) clipboard = os.path.join(current_path_var.get(), item_text[2:]) set_status(f”Copied ‘{os.path.basename(clipboard)}’”)

def paste_item(): global clipboard if not clipboard: return dest = os.path.join(current_path_var.get(), os.path.basename(clipboard)) try: if os.path.isdir(clipboard): shutil.copytree(clipboard, dest) else: shutil.copy2(clipboard, dest) refresh_file_list() set_status(f”Pasted ‘{os.path.basename(clipboard)}’”) except Exception as e: messagebox.showerror(“Error”, str(e))

=========================

Context Menu

=========================

context_menu = tk.Menu(root, tearoff=0) context_menu.add_command(label=“Open”, command=open_selected) context_menu.add_command(label=“Delete”, command=lambda: delete_item()) context_menu.add_command(label=“Rename”, command=rename_item) context_menu.add_separator() context_menu.add_command(label=“Copy”, command=copy_item) context_menu.add_command(label=“Paste”, command=paste_item)

=========================

UI Layout

=========================

Top frame – navigation & actions

top_frame = ttk.Frame(root) top_frame.pack(fill=tk.X, padx=5, pady=5)

path_entry = ttk.Entry(top_frame, textvariable=current_path_var, width=80) path_entry.pack(side=tk.LEFT, padx=(0, 5))

btn_go = ttk.Button(top_frame, text=“Go”, command=lambda: refresh_file_list(current_path_var.get())) btn_go.pack(side=tk.LEFT, padx=2)

btn_up = ttk.Button(top_frame, text=“Up”, command=go_up) btn_up.pack(side=tk.LEFT, padx=2)

btn_new_folder = ttk.Button(top_frame, text=“New Folder”, command=create_folder) btn_new_folder.pack(side=tk.LEFT, padx=2)

dark_check = ttk.Checkbutton( top_frame, text=“Dark Mode”, variable=dark_mode_var, command=toggle_theme ) dark_check.pack(side=tk.RIGHT, padx=2)

Main listbox – file view

list_frame = ttk.Frame(root) list_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)

file_listbox = tk.Listbox( list_frame, selectmode=tk.SINGLE, font=(“Segoe UI”, 10), activestyle=“none” ) file_listbox.pack(fill=tk.BOTH, expand=True, side=tk.LEFT)

Scrollbars

scroll_y = ttk.Scrollbar(list_frame, orient=tk.VERTICAL, command=file_listbox.yview) scroll_y.pack(fill=tk.Y, side=tk.RIGHT) file_listbox.config(yscrollcommand=scroll_y.set)

Bind double‑click and right‑click

file_listbox.bind("", lambda e: open_selected()) file_listbox.bind("", lambda e: context_menu.tk_popup(e.x_root, e.y_root))

Status bar

status_bar = ttk.Label(root, textvariable=status_var, relief=tk.SUNKEN, anchor=tk.W) status_bar.pack(fill=tk.X, side=tk.BOTTOM, ipady=2)

Initial population

refresh_file_list()

root.mainloop()

上下文菜单

context_menu.add_command(label="Paste", command=paste_item)

def show_context_menu(event):
    try:
        selection = file_listbox.nearest(event.y)
        file_listbox.selection_clear(0, tk.END)
        file_listbox.selection_set(selection)
        context_menu.post(event.x_root, event.y_root)
    finally:
        context_menu.grab_release()

状态栏

ttk.Label(root, textvariable=status_var, anchor="w", font=("Segoe UI", 10)).pack(
    side=tk.BOTTOM, fill="x"
)

主框架

main_frame = ttk.Frame(root, padding=20)
main_frame.pack(expand=True, fill="both")

工具栏

toolbar = ttk.Frame(main_frame)
toolbar.pack(fill="x", pady=(0, 10))

ttk.Button(toolbar, text="Up", command=go_up).pack(side="left", padx=5)
ttk.Button(toolbar, text="New Folder", command=create_folder).pack(side="left", padx=5)
ttk.Button(toolbar, text="Delete", command=delete_item).pack(side="left", padx=5)
ttk.Button(toolbar, text="Copy", command=copy_item).pack(side="left", padx=5)
ttk.Button(toolbar, text="Paste", command=paste_item).pack(side="left", padx=5)
ttk.Checkbutton(
    toolbar, text="Dark Mode", variable=dark_mode_var, command=toggle_theme
).pack(side="right", padx=5)

当前路径

path_frame = ttk.Frame(main_frame)
path_frame.pack(fill="x", pady=(0, 10))

ttk.Label(path_frame, text="Current Path:").pack(side="left")
ttk.Entry(path_frame, textvariable=current_path_var, width=80).pack(
    side="left", padx=(5, 0)
)
ttk.Button(
    path_frame,
    text="Go",
    command=lambda: refresh_file_list(current_path_var.get()),
).pack(side="left", padx=5)

文件列表

file_frame = ttk.Frame(main_frame)
file_frame.pack(expand=True, fill="both")

file_listbox = tk.Listbox(file_frame, font=("Segoe UI", 11))
file_listbox.pack(side="left", expand=True, fill="both")
file_listbox.bind("", lambda e: open_selected())
file_listbox.bind("", show_context_menu)

scrollbar = ttk.Scrollbar(file_frame, orient="vertical", command=file_listbox.yview)
scrollbar.pack(side="right", fill="y")
file_listbox.config(yscrollcommand=scrollbar.set)

# Initialize file list
refresh_file_list()

运行应用

root.mainloop()

如何运行

  1. 安装依赖

    pip install sv_ttk
  2. 运行脚本

    python FileMat_v3.py

FileMate Pro – 您的友好 Python 文件管理器,支持暗色模式、复制‑粘贴,并具备所有必备功能,让您轻松浏览和组织文件!

Back to Blog

相关文章

阅读更多 »