DBC_Converter/Test.py
2025-01-03 23:49:59 +09:00

202 lines
9.8 KiB
Python

import os
import tkinter as tk
from tkinter import filedialog, ttk
from tkinter import messagebox
from datetime import datetime
class MainView(tk.Tk):
def __init__(self):
super().__init__()
self.setupUI()
self.setButtons()
self.sortTreeView('파일명', True) # 기본 파일명 오름차순 정렬
def setupUI(self):
self.title("DBC to C Converter")
self.geometry("800x600")
self.tree = ttk.Treeview(self, columns=('파일명', '파일경로', '파일크기'), show='headings')
self.tree.heading('파일명', text='파일명', command=lambda: self.sortTreeView('파일명', False))
self.tree.heading('파일경로', text='파일경로', command=lambda: self.sortTreeView('파일경로', False))
self.tree.heading('파일크기', text='파일크기', command=lambda: self.sortTreeView('파일크기', False))
self.tree.pack(fill=tk.BOTH, expand=True)
for col in self.tree['columns']:
if col == '파일크기':
self.tree.column(col, width=100, stretch=tk.NO) # 파일크기 열의 너비를 작게 설정
else:
self.tree.column(col, stretch=tk.YES)
self.tree.bind("<Motion>", self.onTreeMotion)
self.tree.bind("<Leave>", self.onTreeLeave) # 마우스가 Treeview를 떠날 때 이벤트 바인딩
self.tree.bind("<Double-1>", self.onTreeDoubleClick) # 더블클릭 이벤트 바인딩
self.tree.bind("<Button-3>", self.onRightClick) # 우클릭 이벤트 바인딩
self.alert_frame = tk.Frame(self)
self.alert_frame.pack(fill=tk.BOTH, expand=True)
self.alert_text = tk.Text(self.alert_frame, height=5, state='disabled', wrap='word')
self.alert_text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
self.alert_text.tag_configure("spacing", spacing3=10) # 행 간격 설정
self.scrollbar = tk.Scrollbar(self.alert_frame, command=self.alert_text.yview)
self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
self.alert_text.config(yscrollcommand=self.scrollbar.set)
self.button_frame = tk.Frame(self)
self.button_frame.pack(fill=tk.X)
self.btn_list = tk.Button(self.button_frame, text="파일 추가", command=self.FilesOpen)
self.btn_list.grid(row=0, column=0, padx=5, pady=5)
self.btn_delete = tk.Button(self.button_frame, text="파일 삭제", command=self.deleteSelectedFiles)
self.btn_delete.grid(row=0, column=1, padx=5, pady=5)
self.btn_delete_all = tk.Button(self.button_frame, text="모든 파일 삭제", command=self.deleteAllFiles)
self.btn_delete_all.grid(row=0, column=2, padx=5, pady=5)
self.btn_clear_alerts = tk.Button(self.button_frame, text="알림창 내용 삭제", command=self.clearAlerts)
self.btn_clear_alerts.grid(row=0, column=3, padx=5, pady=5)
self.tree.bind("<Button-1>", self.onTreeClick)
def setButtons(self):
self.btn_list.config(command=self.FilesOpen)
self.btn_delete.config(command=self.deleteSelectedFiles)
self.btn_delete_all.config(command=self.deleteAllFiles)
self.btn_clear_alerts.config(command=self.clearAlerts)
def FilesOpen(self):
file_paths = filedialog.askopenfilenames(
filetypes=[("DBC 파일", "*.dbc"), ("모든 파일", "*.*")]
)
if file_paths:
existing_files = [self.tree.item(item, 'values')[0] for item in self.tree.get_children()]
duplicate_files = [os.path.split(file_path)[1] for file_path in file_paths if os.path.split(file_path)[1] in existing_files]
new_files = [file_path for file_path in file_paths if os.path.split(file_path)[1] not in existing_files]
if duplicate_files:
self.showDuplicateFilesWarning(duplicate_files, new_files, [os.path.split(file_path)[1] for file_path in new_files])
self.updateAlertText(f"중복 파일 경고", duplicate_files)
if new_files:
self.populateTreeView(new_files)
self.updateAlertText(f"파일 추가 완료", [os.path.split(file_path)[1] for file_path in new_files])
def deleteSelectedFiles(self):
selected_items = self.tree.selection()
deleted_files = [self.tree.item(item, 'values')[0] for item in selected_items] # 파일 이름으로 변경
for item in selected_items:
self.tree.delete(item)
self.updateAlertText(f"파일 삭제 완료", deleted_files)
def deleteAllFiles(self):
all_items = self.tree.get_children()
deleted_files = [self.tree.item(item, 'values')[0] for item in all_items]
for item in all_items:
self.tree.delete(item)
self.updateAlertText(f"모든 파일 삭제 완료", deleted_files)
def clearAlerts(self):
self.alert_text.config(state='normal')
self.alert_text.delete('1.0', tk.END)
self.alert_text.config(state='disabled')
def onTreeClick(self, event):
if self.tree.identify_region(event.x, event.y) == "nothing":
self.tree.selection_remove(self.tree.selection())
def onTreeMotion(self, event):
if hasattr(self.tree, 'tooltip'):
self.tree.tooltip.destroy()
region = self.tree.identify_region(event.x, event.y)
if region == "cell":
column = self.tree.identify_column(event.x)
item = self.tree.identify_row(event.y)
if column in ('#1', '#2'): # 파일명, 파일경로 열에 대해서만 툴팁 표시
value = self.tree.item(item, "values")[int(column[1:]) - 1]
self.tree.tooltip = tk.Toplevel(self.tree)
self.tree.tooltip.wm_overrideredirect(True)
self.tree.tooltip.wm_geometry(f"+{event.x_root + 20}+{event.y_root + 10}")
label = tk.Label(self.tree.tooltip, text=value, background="yellow", relief="solid", borderwidth=1, font=("Arial", 10, "normal"))
label.pack()
def onTreeLeave(self, event):
if hasattr(self.tree, 'tooltip'):
self.tree.tooltip.destroy()
def onTreeDoubleClick(self, event):
region = self.tree.identify_region(event.x, event.y)
if region == "cell":
column = self.tree.identify_column(event.x)
item = self.tree.identify_row(event.y)
values = self.tree.item(item, "values")
if column == '#1': # 파일명을 더블클릭한 경우
file_path = os.path.join(values[1], values[0])
os.startfile(file_path)
elif column == '#2': # 경로를 더블클릭한 경우
os.startfile(values[1])
def onRightClick(self, event):
region = self.tree.identify_region(event.x, event.y)
if region == "cell":
column = self.tree.identify_column(event.x)
item = self.tree.identify_row(event.y)
self.tree.selection_set(item) # 우클릭한 항목을 선택
values = self.tree.item(item, "values")
menu = tk.Menu(self, tearoff=0)
menu.add_command(label="파일 열기", command=lambda: os.startfile(os.path.join(values[1], values[0])))
menu.add_command(label="폴더 열기", command=lambda: os.startfile(values[1]))
menu.add_command(label="경로 복사", command=lambda: self.clipboard_append(os.path.join(values[1], values[0])))
menu.add_command(label="파일 삭제", command=lambda: self.deleteFile(item))
menu.post(event.x_root, event.y_root)
def deleteFile(self, item):
file_name = self.tree.item(item, 'values')[0]
self.tree.delete(item)
self.updateAlertText(f"파일 삭제 완료", [file_name])
def populateTreeView(self, file_paths):
def format_file_size(size_in_bytes):
size_in_kb = size_in_bytes / 1024
return f"{size_in_kb:.2f} KB"
for file_path in file_paths:
directory, file = os.path.split(file_path)
fsize = format_file_size(os.path.getsize(file_path))
self.tree.insert('', 'end', values=(file, directory, fsize))
def updateAlertText(self, message, file_list):
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
self.alert_text.config(state='normal')
self.alert_text.insert(tk.END, f"[{current_time}] {message}\n", "spacing")
for file in file_list:
self.alert_text.insert(tk.END, f" - {file}\n", "spacing")
self.alert_text.config(state='disabled')
self.alert_text.see(tk.END)
def showDuplicateFilesWarning(self, duplicate_files, new_files, new_files_names):
duplicate_files_str = "\n".join(duplicate_files)
new_files_str = "\n".join(new_files_names)
if new_files:
messagebox.showwarning("중복 파일 경고", f"중복 파일이 존재합니다\n\n{duplicate_files_str}\n\n\n중복 파일을 제외한 신규 파일을 추가합니다\n\n{new_files_str}", parent=self)
else:
messagebox.showwarning("중복 파일 경고", f"중복 파일이 존재합합니다\n\n{duplicate_files_str}", parent=self)
def sortTreeView(self, col, reverse):
items = [(self.tree.set(k, col), k) for k in self.tree.get_children('')]
items.sort(reverse=reverse)
for index, (val, k) in enumerate(items):
self.tree.move(k, '', index)
# 헤딩에 삼각형 추가
for col_name in self.tree['columns']:
if col_name == col:
direction = '' if reverse else ''
self.tree.heading(col_name, text=f"{col_name} {direction}", command=lambda _col=col_name: self.sortTreeView(_col, not reverse))
else:
self.tree.heading(col_name, text=col_name, command=lambda _col=col_name: self.sortTreeView(_col, False))
if __name__ == '__main__':
app = MainView()
app.mainloop()