Gestionnaire de fichiers Python de 430 lignes pour les débutants et les nuls

salut!



Je voulais résumer mes connaissances en python et j'ai décidé d'écrire un gestionnaire de fichiers pour pc.







Attention!
, !



Importation de bibliothèques:



import tkinter
import os
import subprocess
from tkinter import messagebox
from tkinter import simpledialog


Menu principal:



class MainContextMenu(tkinter.Menu):
	'''      '''
	def __init__(self, main_window, parent):
		super(MainContextMenu, self).__init__(parent, tearoff = 0)
		self.main_window = main_window
		self.add_command(label=" ", command = self.create_dir)
		self.add_command(label=" ", command = self.create_file)

	def popup_menu(self, event):
		'''     '''
		#    -  
		if self.main_window.file_context_menu:
			self.main_window.file_context_menu.unpost()
		if self.main_window.dir_context_menu:
			self.main_window.dir_context_menu.unpost()
		self.post(event.x_root, event.y_root)

	def create_dir(self):
		'''       '''
		dir_name = simpledialog.askstring(" ", "   ")
		if dir_name:
			command = "mkdir {0}".format(dir_name).split(' ')
			#   
			process = subprocess.Popen(command, cwd=self.main_window.path_text.get(), stdout = subprocess.PIPE, stderr = subprocess.PIPE)
			out, err = process.communicate()
			#    
			if err:
				messagebox.showwarning(" !","  .")
			self.main_window.refresh_window()


	def create_file(self):
		'''        '''
		dir_name = simpledialog.askstring(" ", "   ")
		if dir_name:
			command = "touch {0}".format(dir_name).split(' ')
			#   
			process = subprocess.Popen(command, cwd=self.main_window.path_text.get(), stdout = subprocess.PIPE, stderr = subprocess.PIPE)
			out, err = process.communicate()
			#    
			if err:
				messagebox.showwarning(" !","  .")
			self.main_window.refresh_window()



	def insert_to_dir(self):
		'''         '''
		copy_obj = self.main_window.buff
		to_dir = self.main_window.path_text.get()
		if os.path.isdir(self.main_window.buff):
			#   
			process = subprocess.Popen(['cp', '-r', copy_obj, to_dir], stdout = subprocess.PIPE, stderr = subprocess.PIPE)
			out, err = process.communicate()
			if err:
				messagebox.showwarning(" !", err.decode("utf-8"))
		else:
			#   
			process = subprocess.Popen(['cp', '-n', copy_obj, to_dir], stdout = subprocess.PIPE, stderr = subprocess.PIPE)
			out, err = process.communicate()
			#    
			if err:
				messagebox.showwarning(" !",err.decode("utf-8"))
		self.main_window.refresh_window()


Lorsque vous cliquez sur le fichier, un menu contextuel doit s'afficher:



image



class FileContextMenu(tkinter.Menu):
	def __init__(self, main_window, parent):
		super(FileContextMenu, self).__init__(parent, tearoff = 0)
		self.main_window = main_window
		self.add_command(label=" ", command = self.open_file)
		self.add_separator()
		self.add_command(label="", command = self.copy_file)
		self.add_command(label="", command = self.rename_file)
		self.add_separator()
		self.add_command(label="", command = self.delete_file)


	def open_file(self):
		'''      '''
		ext = self.main_window.take_extention_file(self.main_window.selected_file)
		full_path = self.main_window.path_text.get() + self.main_window.selected_file

		if ext in ['txt', 'py', 'html', 'css', 'js']:
			if 'mousepad' in self.main_window.all_program:
				subprocess.Popen(["mousepad", full_path], start_new_session = True)
			else:
				self.problem_message()
		elif ext == 'pdf':
			if 'evince' in self.main_window.all_program:
				subprocess.run(["evince", full_path], start_new_session = True)
			else:
				self.problem_message()
		elif ext in ['png', 'jpeg', 'jpg', 'gif']:
			if 'ristretto' in self.main_window.all_program:
				subprocess.run(["ristretto", full_path], start_new_session = True)
			else:
				self.problem_message()
		else:
			self.problem_message()

	def problem_message(self):
		messagebox.showwarning("   ", ',       ')

	def copy_file(self):
		'''    '''
		#      
		self.main_window.buff = self.main_window.path_text.get() + self.main_window.selected_file
		self.main_window.refresh_window()


	def delete_file(self):
		'''     '''
		full_path = self.main_window.path_text.get() + self.main_window.selected_file
		#   
		process = subprocess.Popen(['rm', full_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
		output, err = process.communicate()
		#    
		if err:
			messagebox.showwarning("   ", '       ')
		self.main_window.refresh_window()

	def rename_file(self):
		'''     '''
		new_name = simpledialog.askstring(" ", "   ")
		if new_name:
			old_file = self.main_window.path_text.get() + self.main_window.selected_file
			new_file = self.main_window.path_text.get() + new_name
			#   
			process = subprocess.Popen(['mv', old_file, new_file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
			output, err = process.communicate()
			#    
			if err:
				messagebox.showwarning("   ", '       ')
			self.main_window.refresh_window()

	def popup_menu(self, event):
		'''     '''
		self.post(event.x_root, event.y_root)
		#    -  
		if self.main_window.main_context_menu:
			self.main_window.main_context_menu.unpost()
		if self.main_window.dir_context_menu:
			self.main_window.dir_context_menu.unpost()
		self.main_window.selected_file = event.widget["text"]



Idem pour l'annuaire:



class DirContextMenu(tkinter.Menu):
	def __init__(self, main_window, parent):
		super(DirContextMenu, self).__init__(parent, tearoff = 0)
		self.main_window = main_window
		self.add_command(label="", command = self.rename_dir)
		self.add_command(label="", command = self.copy_dir)
		self.add_separator()
		self.add_command(label="", command = self.delete_dir)

	def copy_dir(self):
		'''    '''
		self.main_window.buff = self.main_window.path_text.get() + self.main_window.selected_file
		self.main_window.refresh_window()


	def delete_dir(self):
		'''     '''
		full_path = self.main_window.path_text.get() + self.main_window.selected_file
		if os.path.isdir(full_path):
			#   
			process = subprocess.Popen(['rm', '-rf', full_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
			output, err = process.communicate()
			#    
			if err:
				messagebox.showwarning("   ", '       ')
		self.main_window.refresh_window()

	def rename_dir(self):
		'''     '''
		new_name = simpledialog.askstring(" ", "   ")
		if new_name:
			old_dir = self.main_window.path_text.get() + self.main_window.selected_file
			new_dir = self.main_window.path_text.get() + new_name
			#   
			process = subprocess.Popen(['mv', old_dir, new_dir], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
			output, err = process.communicate()
			#    
			if err:
				messagebox.showwarning("   ", '       ')
			self.main_window.refresh_window()

	def popup_menu(self, event):
		'''     '''
		self.post(event.x_root, event.y_root)
		#    -  
		if self.main_window.main_context_menu:
			self.main_window.main_context_menu.unpost()
		if self.main_window.file_context_menu:
			self.main_window.file_context_menu.unpost()
		self.main_window.selected_file = event.widget["text"]



Classe de fenêtre principale:




class MainWindow():
	'''   '''
	def __init__(self):
		self.root = tkinter.Tk()
		self.root.title("FileManager")
		self.root.resizable(width = False, height = False)
		self.root.geometry('450x300')

		self.hidden_dir = tkinter.IntVar()
		self.buff = None
		self.all_program = os.listdir('C:/')

		self.root.bind('<Button-1>', self.root_click)
		self.root.bind('<FocusOut>', self.root_click)

		#top frame
		self.title_frame = tkinter.Frame(self.root)
		self.title_frame.pack(fill = 'both', expand = True)

		#back button
		self.back_button = tkinter.Button(self.title_frame, text = "..", command = self.parent_dir, width = 1, height = 1)
		self.back_button.pack(side = 'left')

		#path entry
		self.path_text = tkinter.StringVar()
		self.path_text.set('/')
		self.current_path = tkinter.Entry(self.title_frame, textvariable = self.path_text, width = 40, state='readonly')
		self.current_path.pack(side = 'left')

		#button show/hidde hidden dir/file
		self.check_button = tkinter.Checkbutton(self.title_frame, text = "Hidden", font = ("Helvetica", 10), padx = 1, pady = 1, variable = self.hidden_dir, command = self.refresh_window)
		self.check_button.pack(side = 'left')

		#main frame
		self.main_frame = tkinter.Frame(self.root)
		self.main_frame.pack()

		# scroll bar
		self.scrollbar_vert = tkinter.Scrollbar(self.main_frame, orient="vertical")
		self.scrollbar_vert.pack(side = 'right', fill = 'y')

		self.scrollbar_hor = tkinter.Scrollbar(self.main_frame, orient="horizontal")
		self.scrollbar_hor.pack(side = 'bottom', fill = 'x')

		#canvas
		self.canvas = tkinter.Canvas(self.main_frame, borderwidth=0,  bg = 'white')
		self.inner_frame = tkinter.Frame(self.canvas,  bg = 'white')

		#  
		self.scrollbar_vert["command"] = self.canvas.yview
		self.scrollbar_hor["command"] = self.canvas.xview

		#  canvas
		self.canvas.configure(yscrollcommand=self.scrollbar_vert.set, xscrollcommand = self.scrollbar_hor.set, width=400, heigh=250)

		self.canvas.pack(side='left', fill='both', expand=True)
		self.canvas.create_window((0,0), window=self.inner_frame, anchor="nw")


		#  
		self.dir_content()


	def root_click(self, event):
		'''       root'''
		#    - 
		if self.file_context_menu:
			self.file_context_menu.unpost()
		if self.main_context_menu:
			self.main_context_menu.unpost()
		if self.dir_context_menu:
			self.dir_context_menu.unpost()

	def dir_content(self):
		'''      '''
		#   
		dir_list = os.listdir(self.path_text.get())
		path = self.path_text.get()

		if not dir_list:
			#  
			self.main_context_menu = MainContextMenu(self, self.canvas)
			self.canvas.bind('<Button-3>', self.main_context_menu.popup_menu)
			if self.buff:
				self.main_context_menu.add_command(label="", command = self.main_context_menu.insert_to_dir)
			self.inner_frame.bind('<Button-3>', self.main_context_menu.popup_menu)
			#   
			self.file_context_menu = None
			#   
			self.dir_context_menu = None
			return None

		#  
		self.main_context_menu = MainContextMenu(self, self.canvas)
		self.canvas.bind('<Button-3>', self.main_context_menu.popup_menu)
		if self.buff:
			self.main_context_menu.add_command(label="", command = self.main_context_menu.insert_to_dir)
		#   
		self.file_context_menu = FileContextMenu(self, self.inner_frame)
		#   
		self.dir_context_menu = DirContextMenu(self, self.inner_frame)


		i = 0
		for item in dir_list:

			if os.path.isdir(str(path) + item):
				# 
				if os.access(str(path) + item, os.R_OK):
					if (not self.hidden_dir.get() and  not item.startswith('.')) or self.hidden_dir.get():
						photo = tkinter.PhotoImage(file ="img/folder.png")

						icon = tkinter.Label(self.inner_frame, image=photo,  bg = 'white')
						icon.image = photo
						icon.grid(row=i+1, column=0)

						folder_name = tkinter.Label(self.inner_frame, text=item,  bg = 'white', cursor = 'hand1')
						folder_name.bind("<Button-1>", self.move_to_dir)
						folder_name.bind("<Button-3>", self.dir_context_menu.popup_menu)
						folder_name.grid(row=i+1, column=1, sticky='w')
				else:
					if (not self.hidden_dir.get() and not item.startswith('.')) or self.hidden_dir.get():
						photo = tkinter.PhotoImage(file ="img/folder_access.png")

						icon = tkinter.Label(self.inner_frame, image=photo,  bg = 'white')
						icon.image = photo
						icon.grid(row=i+1, column=0)

						folder_name = tkinter.Label(self.inner_frame, text=item,  bg = 'white')
						folder_name.bind("<Button-1>", self.move_to_dir)
						folder_name.grid(row=i+1, column=1, sticky='w')

			else:
				# 
				if (not self.hidden_dir.get() and not item.startswith('.')) or self.hidden_dir.get():
					ext = self.take_extention_file(item)
					#, 
					if ext in ['jpeg', 'jpg', 'png', 'gif']:
						photo = tkinter.PhotoImage(file ="img/photo.png")

						icon = tkinter.Label(self.inner_frame, image=photo,  bg = 'white')
						icon.image = photo
						icon.grid(row=i+1, column=0)

						file_name = tkinter.Label(self.inner_frame, text=item,  bg = 'white')
						file_name.grid(row=i+1, column=1, sticky='w')

						file_name.bind("<Button-3>", self.file_context_menu.popup_menu)
					else:
						# 
						if os.access(str(path) + item, os.R_OK):
							photo = tkinter.PhotoImage(file ="img/file.png")

							icon = tkinter.Label(self.inner_frame, image=photo,  bg = 'white')
							icon.image = photo
							icon.grid(row=i+1, column=0)

							folder_name = tkinter.Label(self.inner_frame, text=item,  bg = 'white')
							folder_name.grid(row=i+1, column=1, sticky='w')

							folder_name.bind("<Button-3>", self.file_context_menu.popup_menu)

						else:
							photo = tkinter.PhotoImage(file ="img/file_access.png")

							icon = tkinter.Label(self.inner_frame, image=photo,  bg = 'white')
							icon.image = photo
							icon.grid(row=i+1, column=0)

							folder_name = tkinter.Label(self.inner_frame, text=item,  bg = 'white')
							folder_name.grid(row=i+1, column=1, sticky='w')
			i += 1
		# inner_frame      
		self.inner_frame.update()
		self.canvas.configure(scrollregion=self.canvas.bbox("all"))

	def move_to_dir(self, event):
		'''      '''
		elem = event.widget
		dir_name = elem["text"]
		fool_path = self.path_text.get() + dir_name
		if os.path.isdir(fool_path) and os.access(fool_path, os.R_OK):
			old_path = self.path_text.get()
			self.path_text.set(old_path + dir_name + '/')
			self.root_click('<Button-1>')
			self.refresh_window()


	def parent_dir(self):
		'''      '''
		old_path = [i for i in self.path_text.get().split('/') if i]
		new_path = '/'+'/'.join(old_path[:-1])
		if not new_path:
			new_path = '/'
		if os.path.isdir(new_path):
			if new_path == '/':
				self.path_text.set(new_path)

			else:
				self.path_text.set(new_path + '/')
			self.refresh_window()


	def take_extention_file(self, file_name):
		'''     '''
		ls = file_name.split('.')
		if len(ls)>1:
			return ls[-1]
		else:
			return None

	def refresh_window(self):
		'''      /'''
		for widget in self.inner_frame.winfo_children():
				widget.destroy()
		self.dir_content()
		self.canvas.yview_moveto(0)


Enfin, création d'une fenêtre et emballage des widgets:



win = MainWindow()
win.root.mainloop()


Fichiers, actifs, binaires ici
yadi.sk/d/0A8TnoazXMk1qg



Je serai heureux si vous partagez avec moi une version améliorée de ce programme!

Écrivez: ki1killer@yandex.ru



All Articles