FA-TOOLS — Header Component

آموزش ساخت مرورگر فایل با tkinter

رفیق برنامه‌نویس، تا حالا شده بخوای یه ابزار کوچیک و جمع‌وجور برای مدیریت فایل‌هات بسازی، اما ندونی از کجا شروع کنی؟ یا شاید دنبال راهی هستی که کاربرهات راحت‌تر فایل‌ها رو انتخاب و مرور کنن؟ خب، جات درسته! امروز می‌خوام بهت یاد بدم چطور با `Tkinter` – همون یار قدیمی و دوست‌داشتنی پایتون برای ساخت رابط کاربری گرافیکی – یه مرورگر فایل ساده ولی کارآمد طراحی کنی. با این آموزش، نه فقط یه مرورگر فایل می‌سازی، بلکه دیدت به GUI و پایتون حسابی باز میشه. اگه دنبال ابزارهای حرفه‌ای‌تر یا اسنیپت‌های خفن پایتون و بقیه زبان‌ها هستی، حتماً یه سر به فروشگاه ابزارهای برنامه‌نویسی فا-تولز بزن؛ کلی چیز باحال اونجا منتظرته!

💡 نقشه راه شما برای ساخت مرورگر فایل

آموزش ساخت مرورگر فایل با tkinter — تصویر 1

1. آماده‌سازی میحیط و ابزارها

  • ✔️ نصب پایتون و Tkinter
  • ✔️ درک اولیه از ساختار پروژه

2. طراحی رابط کاربری (GUI)

  • 🎨 پنجره اصلی و لیبل‌ها
  • 📂 ساخت Treeview برای نمایش فایل‌ها
  • دکمه‌ها و اسکرول‌بارها

3. منطق هسته: لیست فایل‌ها

  • ⚙️ استفاده از ماژول `os`
  • 🔄 تابع به‌روزرسانی محتوای پوشه

4. تعامل و رویدادها

  • 👆 کلیک روی فایل‌ها/پوشه‌ها
  • 🔙 دکمه “بازگشت” به پوشه قبل

چرا Tkinter برای ساخت مرورگر فایل؟

آموزش ساخت مرورگر فایل با tkinter — تصویر 2

شاید بپرسی: “چرا `Tkinter`؟ کلی فریمورک UI دیگه هست!” حق با توئه، گزینه‌های زیادی داریم. اما `Tkinter` چند تا مزیت باحال داره که کار رو برای ما، به خصوص برنامه‌نویس‌های پایتون، خیلی راحت می‌کنه:

* **سادگی و سرعت:** یادگیریش آسونه و می‌تونی سریع یه GUI کاربردی بسازی. نیازی به نصب چیز اضافه‌ای نداره، چون همراه پایتون میاد.
* **پشتیبانی از پلتفرم‌های مختلف:** کدی که می‌نویسی، روی ویندوز، مک و لینوکس بدون تغییر اجرا میشه. یعنی یه بار بنویس، همه جا اجرا کن!
* **سبک و کم‌حجم:** برای ابزارهای کوچیک و کاربردی، عالیه و منابع زیادی از سیستم نمی‌گیره.
* **فلسفه پایتونیک:** کاملاً با فلسفه پایتون (سادگی و خوانایی) هم‌راستاست.

خب، حالا که از مزایاش گفتیم، بریم سراغ بخش هیجان‌انگیز: کدنویسی!

گام اول: آماده‌سازی محیط و ساختار اصلی

آموزش ساخت مرورگر فایل با tkinter — تصویر 3

اولین قدم، آماده کردن اسکلت اصلی برنامه‌ست. یه کلاس برای مرورگر فایل تعریف می‌کنیم که همه چیز رو تو خودش نگه داره. این کار به سازماندهی کد کمک زیادی می‌کنه.

“`python
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import os

class FileBrowser(tk.Tk):
def __init__(self):
super().__init__()
self.title(“مرورگر فایل ساده با Tkinter”)
self.geometry(“800×600”)
self.current_path = os.getcwd() # مسیر فعلی، شروع از دایرکتوری جاری

self.create_widgets()
self.update_file_list()

def create_widgets(self):
# این متد رو در ادامه کامل می‌کنیم
pass

def update_file_list(self):
# این متد هم در ادامه کامل میشه
pass

if __name__ == “__main__”:
app = FileBrowser()
app.mainloop()
“`
توی این کد، `tk.Tk` همون پنجره اصلی برنامه ماست. `os.getcwd()` هم بهمون کمک می‌کنه تا از پوشه جاری شروع کنیم. هر برنامه‌نویس پایتونی که بخواد با فایل‌ها کار کنه، ماژول `os` رو باید مثل کف دستش بشناسه. کلی تابع کاربردی داره که کار با مسیرها، فایل‌ها و پوشه‌ها رو ساده می‌کنه. برای اطلاعات بیشتر درباره نحوه استفاده از این ابزارها، می‌تونی سری به اسنیپت‌های پایتون در فا-تولز بزنی.

گام دوم: طراحی رابط کاربری (Widgets)

حالا نوبت به بخش بصری کار می‌رسه. می‌خوایم یه لیبل برای نمایش مسیر فعلی، یه `Treeview` برای لیست کردن فایل‌ها و پوشه‌ها، و چند تا دکمه برای ناوبری اضافه کنیم.

لیبل مسیر فعلی

یه `Label` ساده برای اینکه کاربر بدونه الان کجاست:

“`python
# ادامه متد create_widgets در کلاس FileBrowser

# فریم برای نمایش مسیر جاری
path_frame = tk.Frame(self, bd=2, relief=”groove”)
path_frame.pack(side=”top”, fill=”x”, padx=10, pady=5)

self.path_label = tk.Label(path_frame, text=f”مسیر جاری: {self.current_path}”, anchor=”w”, font=(“Arial”, 10))
self.path_label.pack(side=”left”, fill=”x”, expand=True, padx=5, pady=5)
“`
`bd` و `relief` برای اضافه کردن یکم استایل بصری به فریم هستن، که کاربر راحت‌تر بخش‌ها رو از هم تشخیص بده.

Treeview برای نمایش فایل‌ها

`Treeview` یه ویجت خیلی قدرتمنده که می‌تونیم ازش برای نمایش داده‌های سلسله‌مراتبی استفاده کنیم، مثل لیست فایل‌ها و پوشه‌ها.

“`python
# ادامه متد create_widgets در کلاس FileBrowser

# فریم برای Treeview و اسکرول‌بارها
tree_frame = tk.Frame(self)
tree_frame.pack(fill=”both”, expand=True, padx=10, pady=5)

self.tree = ttk.Treeview(tree_frame, columns=(“Type”, “Size”), show=”tree headings”)
self.tree.heading(“#0″, text=”نام فایل/پوشه”)
self.tree.heading(“Type”, text=”نوع”)
self.tree.heading(“Size”, text=”حجم”)

self.tree.column(“#0”, width=400, minwidth=200, stretch=tk.YES)
self.tree.column(“Type”, width=100, minwidth=50, stretch=tk.NO)
self.tree.column(“Size”, width=100, minwidth=50, stretch=tk.NO)

# اضافه کردن اسکرول‌بار عمودی
yscroll = ttk.Scrollbar(tree_frame, orient=”vertical”, command=self.tree.yview)
yscroll.pack(side=”right”, fill=”y”)
self.tree.configure(yscrollcommand=yscroll.set)

# اضافه کردن اسکرول‌بار افقی
xscroll = ttk.Scrollbar(tree_frame, orient=”horizontal”, command=self.tree.xview)
xscroll.pack(side=”bottom”, fill=”x”)
self.tree.configure(xscrollcommand=xscroll.set)

self.tree.pack(side=”left”, fill=”both”, expand=True)

# رویداد کلیک روی آیتم‌های Treeview
self.tree.bind(“”, self.on_item_double_click)
“`
اینجا دو تا اسکرول‌بار اضافه کردیم تا مرورگر فایل‌مون روی هر صفحه‌ای (از موبایل و تبلت گرفته تا لپ‌تاپ و حتی تلویزیون!) به درستی نمایش داده بشه و کاربر بتونه محتویات طولانی رو هم به راحتی ببینه. `Double-1` هم یعنی با دو بار کلیک چپ، تابع `on_item_double_click` صدا زده بشه.

دکمه‌ها برای ناوبری

یه دکمه “بازگشت” برای رفتن به پوشه قبلی و یه دکمه برای “انتخاب پوشه” اضافه می‌کنیم.

“`python
# ادامه متد create_widgets در کلاس FileBrowser

# فریم برای دکمه‌ها
button_frame = tk.Frame(self, bd=2, relief=”raised”)
button_frame.pack(side=”bottom”, fill=”x”, padx=10, pady=5)

back_button = tk.Button(button_frame, text=”↑ بازگشت”, command=self.go_up_directory, font=(“Arial”, 10, “bold”), bg=”#E74C3C”, fg=”white”)
back_button.pack(side=”left”, padx=5, pady=5)

select_folder_button = tk.Button(button_frame, text=”انتخاب پوشه”, command=self.select_directory, font=(“Arial”, 10, “bold”), bg=”#2ECC71″, fg=”white”)
select_folder_button.pack(side=”right”, padx=5, pady=5)
“`
دکمه‌ها با رنگ‌های جذاب و فونت بولد، هم کاربردی هستن و هم به ظاهر برنامه جلوه میدن.

گام سوم: منطق هسته – به‌روزرسانی لیست فایل‌ها

مهم‌ترین بخش مرورگر فایل، تابعیه که محتویات یه پوشه رو بخونه و توی `Treeview` نمایش بده. این تابع باید بتونه بین فایل و پوشه تمایز قائل بشه و اطلاعاتی مثل حجم فایل رو هم نشون بده.

“`python
# ادامه متد update_file_list در کلاس FileBrowser

def update_file_list(self):
self.tree.delete(*self.tree.get_children()) # پاک کردن آیتم‌های قبلی
self.path_label.config(text=f”مسیر جاری: {self.current_path}”) # به‌روزرسانی لیبل مسیر

try:
for item in os.listdir(self.current_path):
full_path = os.path.join(self.current_path, item)
if os.path.isdir(full_path):
# پوشه
self.tree.insert(“”, “end”, iid=full_path, text=item, values=(“پوشه”, “”), image=self.folder_icon)
else:
# فایل
try:
size = os.path.getsize(full_path)
size_str = self.format_size(size)
except OSError:
size_str = “N/A” # اگر فایل قابل دسترسی نبود
self.tree.insert(“”, “end”, iid=full_path, text=item, values=(“فایل”, size_str), image=self.file_icon)
except PermissionError:
messagebox.showerror(“خطا”, “دسترسی به این پوشه مجاز نیست!”)
self.go_up_directory() # برگرد به پوشه قبلی
except Exception as e:
messagebox.showerror(“خطا”, f”مشکلی پیش آمد: {e}”)
self.go_up_directory()

def format_size(self, size_bytes):
“””تبدیل بایت به واحد خواناتر (KB, MB, GB)”””
if size_bytes < 1024:
return f"{size_bytes} B"
elif size_bytes < 1024**2:
return f"{size_bytes / 1024:.2f} KB"
elif size_bytes < 1024**3:
return f"{size_bytes / (1024**2):.2f} MB"
else:
return f"{size_bytes / (1024**3):.2f} GB"

def load_icons(self):
"""لود کردن آیکون‌های پوشه و فایل"""
# می‌توانید آیکون‌های سفارشی خود را اینجا بارگذاری کنید
# برای سادگی، از آیکون‌های داخلی Tkinter استفاده می‌کنیم یا Placeholder
try:
self.folder_icon = tk.PhotoImage(file="icons/folder.png") # فرض بر وجود آیکون folder.png در پوشه icons
self.file_icon = tk.PhotoImage(file="icons/file.png") # فرض بر وجود آیکون file.png در پوشه icons
except tk.TclError:
# اگر آیکون‌ها پیدا نشدند، از یک placeholder استفاده می‌کنیم یا آنها را خالی می‌گذاریم
print("Warning: Custom icons not found. Using default or no icons.")
self.folder_icon = None
self.file_icon = None

# در __init__ متد، بعد از super().__init__() این خط را اضافه کنید:
# self.load_icons()
“`
تابع `update_file_list` هر بار که مسیر عوض میشه، `Treeview` رو پاک می‌کنه و محتویات پوشه جدید رو نمایش میده. ماژول `os` اینجا نقش کلیدی داره. با `os.listdir()` لیست فایل‌ها رو می‌گیریم، با `os.path.isdir()` چک می‌کنیم پوشه‌ست یا فایل، و با `os.path.join()` مسیر کامل رو می‌سازیم. `os.path.getsize()` هم حجم فایل رو بهمون میده. در قسمت آیکون‌ها، می‌توانید آیکون‌های دلخواهتان را با فرمت `.png` یا `.gif` استفاده کنید. فقط کافیه مسیر درست رو به `tk.PhotoImage` بدید.

گام چهارم: تعامل با کاربر و مدیریت رویدادها

حالا باید برنامه‌مون رو تعاملی کنیم. یعنی وقتی کاربر روی یه آیتم توی `Treeview` دو بار کلیک می‌کنه، اگر پوشه بود، وارد اون پوشه بشه و اگر فایل بود، یه کاری انجام بده (مثلاً مسیر فایل رو نمایش بده). همچنین باید دکمه “بازگشت” رو هم فعال کنیم.

رویداد دو بار کلیک

“`python
# ادامه کلاس FileBrowser

def on_item_double_click(self, event):
selected_item = self.tree.focus() # آیتم انتخاب شده
if not selected_item:
return

item_path = self.tree.item(selected_item, “iid”) # مسیر کامل آیتم
if os.path.isdir(item_path):
self.current_path = item_path
self.update_file_list()
else:
# اینجا می‌تونی کاری با فایل انجام بدی، مثلاً مسیرش رو نمایش بدی
messagebox.showinfo(“فایل انتخاب شده”, f”مسیر فایل: {item_path}”)
# برای مثال، می‌تونی فایل رو با برنامه پیش‌فرض باز کنی
# os.startfile(item_path) # فقط برای ویندوز
“`

دکمه بازگشت (Go Up)

“`python
# ادامه کلاس FileBrowser

def go_up_directory(self):
parent_dir = os.path.dirname(self.current_path)
if parent_dir != self.current_path: # برای جلوگیری از برگشت به ریشه درایوها
self.current_path = parent_dir
self.update_file_list()

def select_directory(self):
chosen_dir = filedialog.askdirectory(initialdir=self.current_path)
if chosen_dir:
self.current_path = chosen_dir
self.update_file_list()
“`
`os.path.dirname()` مسیر پوشه والد رو برمی‌گردونه. با این تابع، می‌تونیم به راحتی به پوشه بالایی برگردیم. `filedialog.askdirectory()` هم یه پنجره استاندارد برای انتخاب پوشه باز می‌کنه.

گام پنجم: بهبود و عیب‌یابی سریع

خب، تا اینجا یه مرورگر فایل پایه و کاربردی ساختیم. اما همیشه جا برای بهتر شدن هست. یه برنامه‌نویس خوب، کسیه که مشکلات احتمالی رو پیش‌بینی و حل کنه.

جدول مقایسه‌ای ویجت‌های Tkinter برای نمایش داده

ویجت کاربرد اصلی
`ttk.Treeview` نمایش داده‌های سلسله‌مراتبی (مثل فایل‌ها و پوشه‌ها)، داده‌های جدولی پیچیده.
`tk.Listbox` نمایش لیست ساده از آیتم‌ها، مناسب برای انتخاب تک یا چند آیتم.

عیب‌یابی سریع و راه‌حل‌ها

این بخش برای مواقعیه که به مشکل برمی‌خوری. نگران نباش، اینا طبیعیه و برای هر برنامه‌نویسی پیش میاد. اگه دوست داری اسنیپت‌های بیشتر در مورد خطاهای رایج پایتون رو ببینی، به صفحه اصلی اسنیپت‌ها سر بزن.

🔴 مشکل: PermissionError (خطای دسترسی)

وقتی روی یک پوشه خاص کلیک می‌کنید، برنامه از کار می‌افتد و خطای PermissionError دریافت می‌کنید.

📝 راه‌حل: این خطا به این معنی است که برنامه شما اجازه دسترسی به آن پوشه را ندارد (مثلاً پوشه‌های سیستمی ویندوز). برای رفع این مشکل، ما داخل تابع update_file_list یک بلاک try-except برای PermissionError قرار دادیم. این بلاک باعث می‌شود به جای کرش کردن برنامه، یک پیام خطا به کاربر نمایش داده شود و برنامه به پوشه قبلی بازگردد. همیشه سعی کن برای عملیات‌های فایل، مدیریت خطا (Error Handling) قوی داشته باشی.

🟠 مشکل: آیکون‌ها نمایش داده نمی‌شوند یا خطای Tk.TclError می‌دهند.

بعد از اضافه کردن بخش آیکون‌ها، یا آیکونی نمی‌بینید یا برنامه با خطایی شبیه _tkinter.TclError: couldn't open "icons/folder.png": no such file or directory مواجه می‌شود.

📝 راه‌حل: این یعنی فایل‌های آیکون (folder.png و file.png) در مسیر درستی قرار ندارند یا اصلاً وجود ندارند. مطمئن شو که:

  • فایل‌های آیکون رو در مسیری که توی کد مشخص کردی (مثلاً یه پوشه به اسم icons کنار اسکریپت پایتونیت) قرار دادی.
  • اسم فایل‌ها رو دقیق نوشتی و فرمتشون .png یا .gif باشه. Tkinter فقط از این فرمت‌ها پشتیبانی می‌کنه.

برای اینکه برنامه کرش نکنه، ما در متد load_icons از یک بلاک try-except استفاده کردیم که اگر آیکون‌ها پیدا نشدند، برنامه به کار خود ادامه دهد و فقط یک پیام هشدار چاپ کند.

🔵 مشکل: برنامه در زمان اجرای طولانی کند می‌شود.

اگر Treeview شما هزاران فایل و پوشه را نمایش دهد، ممکن است کندی و لگ در رابط کاربری را تجربه کنید.

📝 راه‌حل: برای مرورگرهای فایل پیشرفته‌تر که با پوشه‌های خیلی بزرگ سروکار دارند، بهتر است از بارگذاری تنبل (Lazy Loading) استفاده کنید. یعنی فقط محتویات پوشه فعلی را بارگذاری کنید و وقتی کاربر روی یک پوشه جدید کلیک می‌کند، آن را بارگذاری کنید. در این مثال، ما همین کار را کردیم، اما اگر پوشه فعلی هم خودش شامل تعداد بسیار زیادی آیتم باشد، باید به فکر یک الگوریتم بهینه‌تر باشید، مثلاً صفحه‌بندی (Pagination) یا بارگذاری تدریجی با استفاده از تردها (Threading) تا رابط کاربری فریز نشود. همچنین، برای مرورگرهای فایل خیلی پیشرفته، ممکنه نیاز باشه به جای `Treeview` از فریمورک‌های قوی‌تری مثل `PyQt` یا `Kivy` استفاده کنی، یا یکمی توی اسنیپت‌های وردپرس به دنبال ایده‌های جدید برای مدیریت داده‌های بزرگ بگردی.

حرف آخر و نکات مهم

تبریک میگم! تو الان یه مرورگر فایل پایه و کاربردی با `Tkinter` ساختی. این فقط شروع کاره. می‌تونی این مرورگر رو با اضافه کردن قابلیت‌هایی مثل:

* **جستجو (Search):** یک فیلد برای جستجوی فایل‌ها و پوشه‌ها.
* **عملیات فایل (File Operations):** دکمه‌هایی برای کپی، کات، پیست، حذف و تغییر نام فایل‌ها.
* **فیلتر (Filter):** گزینه‌ای برای نمایش فقط فایل‌ها، فقط پوشه‌ها یا فیلتر بر اساس پسوند فایل.
* **پیش‌نمایش (Preview):** نمایش محتوای فایل‌های متنی یا تصاویر کوچک.

…به یه ابزار قدرتمندتر تبدیل کنی. برای ایده‌های بیشتر در مورد طراحی UI و UX، می‌تونی سری به اسنیپت‌های CSS، HTML و JavaScript بزنی که با اینکه برای وب هستن، مفاهیمشون توی طراحی GUI هم به دردت می‌خورن.

این مقاله رو طوری نوشتم که کاملاً جامع و مشکل‌گشا باشه، هر جایی که به مشکل خوردی، بتونی سریع راه حل رو پیدا کنی. یادت باشه، برنامه‌نویسی یعنی حل مساله، و هر ابزاری که بسازی، یه قدم تو این مسیره. اگه سوالی داشتی یا نیاز به راهنمایی بیشتر بود، حتماً با ما در تماس باش: 09202232789. ما همیشه برای کمک بهت آماده‌ایم!

کد کامل و نهایی مرورگر فایل

برای راحتی شما، کد کامل مرورگر فایل رو اینجا آوردم. این کدیه که تمام بخش‌های آموزشی بالا رو ترکیب کرده. می‌تونی مستقیماً این کد رو کپی کنی و اجراش کنی.

“`python
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import os

class FileBrowser(tk.Tk):
def __init__(self):
super().__init__()
self.title(“مرورگر فایل ساده با Tkinter”)
self.geometry(“800×600”)
self.current_path = os.getcwd()

self.load_icons() # بارگذاری آیکون‌ها
self.create_widgets()
self.update_file_list()

def load_icons(self):
“””لود کردن آیکون‌های پوشه و فایل (می‌توانید مسیرها را به آیکون‌های سفارشی تغییر دهید)”””
try:
# فرض بر وجود پوشه ‘icons’ در کنار اسکریپت و داشتن فایل‌های folder.png و file.png
# برای استفاده از آیکون‌های پیش‌فرض سیستم، این خطوط را حذف یا تغییر دهید.
script_dir = os.path.dirname(__file__)
self.folder_icon = tk.PhotoImage(file=os.path.join(script_dir, “icons”, “folder.png”))
self.file_icon = tk.PhotoImage(file=os.path.join(script_dir, “icons”, “file.png”))
except tk.TclError:
print(“Warning: Custom icons not found or invalid. Using default or no icons.”)
self.folder_icon = None # می‌توانید از آیکون‌های داخلی Tkinter مانند ‘::tk::icons::folder’ استفاده کنید
self.file_icon = None # یا ‘::tk::icons::document’ برای ویندوز و مک

def create_widgets(self):
# فریم برای نمایش مسیر جاری
path_frame = tk.Frame(self, bd=2, relief=”groove”, bg=”#ECF0F1″)
path_frame.pack(side=”top”, fill=”x”, padx=10, pady=5)

self.path_label = tk.Label(path_frame, text=f”مسیر جاری: {self.current_path}”, anchor=”w”, font=(“Arial”, 10, “bold”), bg=”#ECF0F1″, fg=”#2C3E50″)
self.path_label.pack(side=”left”, fill=”x”, expand=True, padx=5, pady=5)

# فریم برای Treeview و اسکرول‌بارها
tree_frame = tk.Frame(self)
tree_frame.pack(fill=”both”, expand=True, padx=10, pady=5)

self.tree = ttk.Treeview(tree_frame, columns=(“Type”, “Size”), show=”tree headings”)
self.tree.heading(“#0″, text=”نام فایل/پوشه”, anchor=”w”)
self.tree.heading(“Type”, text=”نوع”, anchor=”w”)
self.tree.heading(“Size”, text=”حجم”, anchor=”e”) # حجم به سمت راست

self.tree.column(“#0”, width=400, minwidth=200, stretch=tk.YES)
self.tree.column(“Type”, width=100, minwidth=50, stretch=tk.NO)
self.tree.column(“Size”, width=100, minwidth=50, stretch=tk.NO)

# اضافه کردن اسکرول‌بار عمودی
yscroll = ttk.Scrollbar(tree_frame, orient=”vertical”, command=self.tree.yview)
yscroll.pack(side=”right”, fill=”y”)
self.tree.configure(yscrollcommand=yscroll.set)

# اضافه کردن اسکرول‌بار افقی
xscroll = ttk.Scrollbar(tree_frame, orient=”horizontal”, command=self.tree.xview)
xscroll.pack(side=”bottom”, fill=”x”)
self.tree.configure(xscrollcommand=xscroll.set)

self.tree.pack(side=”left”, fill=”both”, expand=True)

self.tree.bind(“”, self.on_item_double_click)

# فریم برای دکمه‌ها
button_frame = tk.Frame(self, bd=2, relief=”raised”, bg=”#BDC3C7″)
button_frame.pack(side=”bottom”, fill=”x”, padx=10, pady=5)

back_button = tk.Button(button_frame, text=”↑ بازگشت”, command=self.go_up_directory, font=(“Arial”, 10, “bold”), bg=”#E74C3C”, fg=”white”, activebackground=”#C0392B”, activeforeground=”white”)
back_button.pack(side=”left”, padx=5, pady=5)

select_folder_button = tk.Button(button_frame, text=”انتخاب پوشه”, command=self.select_directory, font=(“Arial”, 10, “bold”), bg=”#2ECC71″, fg=”white”, activebackground=”#27AE60″, activeforeground=”white”)
select_folder_button.pack(side=”right”, padx=5, pady=5)

def update_file_list(self):
self.tree.delete(*self.tree.get_children())
self.path_label.config(text=f”مسیر جاری: {self.current_path}”)

try:
for item in os.listdir(self.current_path):
full_path = os.path.join(self.current_path, item)
if os.path.isdir(full_path):
self.tree.insert(“”, “end”, iid=full_path, text=item, values=(“پوشه”, “”), image=self.folder_icon)
else:
try:
size = os.path.getsize(full_path)
size_str = self.format_size(size)
except OSError:
size_str = “N/A”
self.tree.insert(“”, “end”, iid=full_path, text=item, values=(“فایل”, size_str), image=self.file_icon)
except PermissionError:
messagebox.showerror(“خطا”, “دسترسی به این پوشه مجاز نیست!”)
self.go_up_directory()
except Exception as e:
messagebox.showerror(“خطا”, f”مشکلی پیش آمد: {e}”)
self.go_up_directory()

def format_size(self, size_bytes):
“””تبدیل بایت به واحد خواناتر (KB, MB, GB)”””
if size_bytes < 1024:
return f"{size_bytes} B"
elif size_bytes < 1024**2:
return f"{size_bytes / 1024:.2f} KB"
elif size_bytes < 1024**3:
return f"{size_bytes / (1024**2):.2f} MB"
else:
return f"{size_bytes / (1024**3):.2f} GB"

def on_item_double_click(self, event):
selected_item = self.tree.focus()
if not selected_item:
return

item_path = self.tree.item(selected_item, "iid")
if os.path.isdir(item_path):
self.current_path = item_path
self.update_file_list()
else:
messagebox.showinfo("فایل انتخاب شده", f"مسیر فایل: {item_path}")
# مثال: باز کردن فایل با برنامه پیش‌فرض (فقط برای سیستم‌عامل‌های خاص)
# try:
# os.startfile(item_path) # برای ویندوز
# except AttributeError:
# try:
# import subprocess
# subprocess.call(['open', item_path]) # برای مک
# except:
# subprocess.call(['xdg-open', item_path]) # برای لینوکس
# except Exception as e:
# messagebox.showerror("خطا در باز کردن فایل", f"نتوانست فایل را باز کند: {e}")

def go_up_directory(self):
parent_dir = os.path.dirname(self.current_path)
if parent_dir and parent_dir != self.current_path:
self.current_path = parent_dir
self.update_file_list()
elif os.path.ismount(self.current_path) and os.path.ismount(parent_dir): # برای کنترل ریشه درایوها در ویندوز
messagebox.showinfo("اطلاعات", "شما در ریشه درایو هستید.")

def select_directory(self):
chosen_dir = filedialog.askdirectory(initialdir=self.current_path)
if chosen_dir:
self.current_path = chosen_dir
self.update_file_list()

if __name__ == "__main__":
app = FileBrowser()
app.mainloop()

“`

Table of Contents

آخرین نوشته‌ها