Folder Mangement has been added

This commit is contained in:
Falko Victor Habel 2024-03-10 16:39:21 +01:00
parent f1b9470b1b
commit b0a37e1ae7
3 changed files with 309 additions and 0 deletions

View File

@ -0,0 +1,93 @@
import customtkinter as Ctk
import os
import scripts.get_sys_info as system_code
from ..SaveData import SaveData
FONT = "Berlin Sans FB"
class CreateFolder(Ctk.CTkFrame):
def __init__(self,master, output_path,callback, **kwargs):
super().__init__(master, **kwargs)
system_code.load_json_file()
self.data_saver = SaveData()
self.my_font = Ctk.CTkFont(family=FONT, size=22)
self.output_path = output_path
self.callback = callback
self.error_txt = ""
self.create_folder()
def enable_keybinding(self):
self.master.bind("<Return>", self.on_a_press, add="+")
def disable_keybinding(self):
self.master.unbind("<Return>")
def on_a_press(self, event):
# Check if the frame is visible by querying its manager info
if self.winfo_manager():
self.create_new_data_folder()
def create_folder(self):
self.enable_keybinding()
self.create_folder_label = Ctk.CTkLabel(self, text="Type name for new Object:", width=100, font=self.my_font)
self.create_folder_entry = Ctk.CTkEntry(self, placeholder_text="New Data Object", width=100, font=self.my_font)
self.create_folder_name_btn = Ctk.CTkButton(self, text="Create", width=100, command=self.create_new_data_folder, font=self.my_font)
self.create_folder_error = Ctk.CTkLabel(self, text=self.error_txt, width=100, font=self.my_font)
self.place_create_folder()
def create_new_data_folder(self):
"""
Create a new folder in the directory specified by self.output_path.
The folder name will be 'data_folder'. If the folder already exists, a number will be appended
to create a unique folder name ('data_folder_1', 'data_folder_2', etc.).
"""
folder_name = self.create_folder_entry.get()
# Construct the full path for the new data folder
full_path = os.path.join(self.output_path, folder_name)
if os.path.exists(full_path):
self.error_txt = "The folder exists already"
self.create_folder_error.configure(text=self.error_txt)
return
try:
os.makedirs(full_path)
print(f"Folder created at: {full_path}")
self.data_saver.create(full_path)
except OSError:
self.error_txt = "There occured an error creating the Folder"
self.create_folder_error.configure(text=self.error_txt)
self.callback(full_path)
def place_create_folder(self):
self.create_folder_label.place(
relx=0.5,
rely=0.425,
relwidth=0.3,
relheight=0.06,
anchor="center",
) # Position the converter button to the left
self.create_folder_entry.place(
relx=0.3875,
rely=0.5,
relwidth=0.125,
relheight=0.06,
anchor="w",
) # Position the converter button to the left
self.create_folder_name_btn.place(
relx=0.6125,
rely=0.5,
relwidth=0.08,
relheight=0.06,
anchor="e",
) # Adjusted for .place
self.create_folder_error.place(
relx=0.5,
rely=0.575,
relwidth=0.3,
relheight=0.06,
anchor="center",
) # Position the converter button to the left

View File

@ -0,0 +1,99 @@
import customtkinter as Ctk
import os
from PIL import Image
from ..SaveData import SaveData
import scripts.get_sys_info as system_code
FONT = "Berlin Sans FB"
class OpenFolder(Ctk.CTkScrollableFrame):
def __init__(self,master,output_path, callback, **kwargs, ):
super().__init__(master, **kwargs)
self.my_font = Ctk.CTkFont(family=FONT, size=16)
self.warning_font = Ctk.CTkFont(family=FONT, size=20)
# the variables needed to get from the upper class
self.button_image = Ctk.CTkImage(Image.open(r"./icons/folder.png"), size=(63, 63))
self.output_path = output_path
self.callback = callback # Store the callback function
system_code.load_json_file()
self.data_saver = SaveData()
self.folders = self.get_all_folders()
self.button_size = (50, 50) # Size width and height
self.padding = 10 # Padding around each button
if len(self.folders) == 0:
self.folder_has_no_subs()
else:
self.make_buttons()
self.bind("<Configure>", self.on_configure, '+')
def on_configure(self, event=None):
self.rearrange_buttons()
def get_button_widths(self):
"""
Estimates button widths based on button text size.
"""
average_char_width = 8
width = max(len(button._text) * average_char_width for button in self.buttons)
return max(width, self.button_size[0])
def get_max_folders_per_row(self):
"""
Calculate the maximum number of folders that can fit in a row based on the container's width.
"""
container_width = self.winfo_width()
button_width = self.get_button_widths()
# Calculate the space required for one button including padding
total_button_width = button_width + 2 * self.padding
# Divide the available space in the container by the space required for one button
max_folders_per_row = max(1, container_width // total_button_width)
return max_folders_per_row
def get_all_folders(self):
folders = {f.name: f.path for f in os.scandir(self.output_path) if f.is_dir()}
return dict(sorted(folders.items()))
def rearrange_buttons(self):
"""
Rearrange buttons based on the current window size and calculated folders per row.
If the window size changes, it recalculates the arrangement.
"""
max_folders_per_row = self.get_max_folders_per_row()
for index, button in enumerate(self.buttons):
row = index // max_folders_per_row
col = index % max_folders_per_row
button.grid(row=row, column=col, padx=self.padding, pady=self.padding)
def make_buttons(self):
"""
Generates buttons for each folder provided.
"""
self.buttons = []
for key, value in self.folders.items():
folder_btn = Ctk.CTkButton(
self, text=key,
width=self.button_size[0], height=self.button_size[1],
image=self.button_image, # Corrected: Use self.button_image for the image parameter
compound="top", # Position text below the image
command=lambda val=value: self.new_folder_chosen(val),
font=self.my_font
)
folder_btn.grid_remove()
self.buttons.append(folder_btn)
self.rearrange_buttons() # Rearrange buttons after creation
def new_folder_chosen(self, folder_path):
"""
Callback for when a new folder is chosen.
"""
self.data_saver.search_in_folder(folder_path)
self.callback(folder_path) # Call the callback passing the current value
def folder_has_no_subs(self):
self.place_forget()
self.label = Ctk.CTkLabel(self, text="No Folders were found", width=100, font=self.warning_font)
self.label.grid(row = 1, column = 1, padx= 50, pady = 50)

View File

@ -0,0 +1,117 @@
import customtkinter as Ctk
import os
import scripts.get_sys_info as system_code
from ..SaveData import SaveData
from tkinter import filedialog
FONT = "Berlin Sans FB"
class SwitchFolder(Ctk.CTkFrame):
def __init__(self,master, callback, **kwargs):
super().__init__(master, **kwargs)
system_code.load_json_file()
self.data_saver = SaveData()
self.my_font = Ctk.CTkFont(family=FONT, size=22)
self.callback = callback
self.error_txt = ""
self.input_path = None
self.output_path = None
self.img_paths = None
self.create_selection()
# the selection part
def create_selection(self):
# input
self.input_entry = Ctk.CTkEntry(self, placeholder_text="Input folder path", width=100, font=self.my_font)
self.input_btn = Ctk.CTkButton(self, text="Browse", width=100, command=self.get_folder_path, font=self.my_font)
# output
self.output_entry = Ctk.CTkEntry(self, placeholder_text="Output folder path", width=100, font=self.my_font)
self.output_btn = Ctk.CTkButton(self, text="Browse", width=100, command=self.get_project_path, font=self.my_font)
# start
self.start_btn = Ctk.CTkButton(self, text="Start", width=100, command=self.open_labeling, font=self.my_font)
self.error_label = Ctk.CTkLabel(self, text=self.error_txt, width=100, font=self.my_font)
self.place_label_selection()
def open_labeling(self):
source_path = self.input_entry.get()
self.output_path = self.output_entry.get()
if not os.path.exists(source_path):
self.error_txt = "Source Folder could not be found"
self.error_label.configure(text=self.error_txt)
elif not os.path.exists(self.output_path):
self.error_txt = "Output Folder could not be found"
self.error_label.configure(text=self.error_txt)
else:
self.data_saver.search_in_folder(self.output_path)
self.img_paths = self.load_images_into_array(source_path)
self.give_back()
def load_images_into_array(self, folder_path):
image_paths = []
for filename in os.listdir(folder_path):
if filename.endswith(system_code.img_format_options):
img_path = os.path.join(folder_path, filename)
image_paths.append(img_path)
return image_paths
def get_folder_path(self):
file_path = filedialog.askdirectory()
self.input_entry.delete(0, Ctk.END) # Delete any existing text in the Entry widget
self.input_entry.insert(0, file_path) # Insert the new text
def get_project_path(self):
video_path = filedialog.askdirectory()
self.output_entry.delete(0, Ctk.END) # Delete any existing text in the Entry widget
self.output_entry.insert(0, video_path) # Insert the new text
def give_back(self):
self.callback(self.img_paths, self.output_path)
def place_label_selection(self):
# output placing
self.input_entry.place(
relx=0.10,
rely=0.4,
anchor="w",
relwidth=0.5,
relheight=0.06
) # Position the converter button to the left
self.input_btn.place(
relx=0.90,
rely=0.4,
anchor="e",
relwidth=0.2,
relheight=0.06
) # Position the converter button to the left
# output placing
self.output_entry.place(
relx=0.10,
rely=0.5,
anchor="w",
relwidth=0.5,
relheight=0.06
) # Position the converter button to the left
self.output_btn.place(
relx=0.90,
rely=0.5,
anchor="e",
relwidth=0.2,
relheight=0.06
) # Position the converter button to the left
# button row
self.start_btn.place(
relx=0.5,
rely=0.6,
anchor="center",
relwidth=0.8,
relheight=0.06
) # Position the converter button to the left
self.error_label.place(
relx=0.5,
rely=0.7,
anchor="center",
relwidth=0.8,
relheight=0.06
) # Position the converter button to the left