Mycar_Browser/modules/ui/tools_widget.py

383 lines
15 KiB
Python

from PySide6.QtWidgets import (QWidget, QVBoxLayout, QTabWidget, QPushButton,
QLabel, QLineEdit, QListWidget, QTextEdit)
from PySide6.QtCore import Qt, Signal, Slot
from modules.xlsFilter.xls_filter_dialog import XlsFilterDialog
# Fluent Widgets 추가
from qfluentwidgets import (ScrollArea, ExpandLayout, SimpleCardWidget, SettingCardGroup,
SwitchSettingCard, ComboBoxSettingCard, ToolButton, FluentIcon,
PrimaryPushButton, InfoBar, InfoBarPosition, SpinBox, LineEdit,
TextEdit, ListWidget, PushButton, TabWidget, SmoothScrollArea)
class ToolsWidget(ScrollArea):
# 시그널 정의
status_changed = Signal(str)
def __init__(self, parent=None, thread_pool=None, logger=None, forbidden_words=None, category_manager=None):
super().__init__(parent)
self.parent = parent
self.thread_pool = thread_pool
self.logger = logger
self.forbidden_words = forbidden_words
self.category_manager = category_manager
if self.logger:
self.logger.info("도구 위젯 초기화 시작")
self.setup_ui()
if self.logger:
self.logger.info("도구 위젯 초기화 완료")
def setup_ui(self):
# 스크롤 영역 설정
self.setWidgetResizable(True)
# 메인 위젯 및 레이아웃
self.main_widget = QWidget()
self.expand_layout = ExpandLayout(self.main_widget)
# 탭 위젯 생성
self.tab_widget = TabWidget(self.main_widget)
# 배송비 계산기 탭
self.shipping_calc_tab = QWidget()
self.setup_shipping_calc_tab()
self.tab_widget.addTab(self.shipping_calc_tab, "배송비 계산기")
# 금지어 관리 탭
self.forbidden_words_tab = QWidget()
self.setup_forbidden_words_tab()
self.tab_widget.addTab(self.forbidden_words_tab, "금지어 관리")
# 카테고리 관리 탭
self.category_tab = QWidget()
self.setup_category_tab()
self.tab_widget.addTab(self.category_tab, "카테고리 관리")
# 로그 관리 탭
self.log_tab = QWidget()
self.setup_log_tab()
self.tab_widget.addTab(self.log_tab, "로그 관리")
# 엑셀 필터링 탭
self.xls_filter_tab = QWidget()
self.setup_xls_filter_tab()
self.tab_widget.addTab(self.xls_filter_tab, "엑셀 필터링")
# 카드 그룹 추가
card_group = SettingCardGroup("도구 모음", self.main_widget)
card_text = "다양한 도구를 탭을 통해 사용할 수 있습니다."
# 도구 카드 추가
self.tools_card = SimpleCardWidget(FluentIcon.SETTING, "도구 모음", card_text, self.main_widget)
self.tools_card.setFixedHeight(120)
self.tools_card.setFixedWidth(self.width())
# 레이아웃에 위젯 추가
self.expand_layout.addWidget(self.tools_card)
self.expand_layout.addWidget(card_group)
self.expand_layout.addWidget(self.tab_widget)
# 위젯 설정
self.setWidget(self.main_widget)
def setup_shipping_calc_tab(self):
layout = QVBoxLayout(self.shipping_calc_tab)
# 설정 카드 그룹
card_group = SettingCardGroup("배송비 계산", self.shipping_calc_tab)
# 무게 입력
self.weight_input = SpinBox(self.shipping_calc_tab)
self.weight_input.setRange(0, 100)
self.weight_input.setSuffix(" kg")
self.weight_input.setToolTip("배송 상품의 무게를 입력하세요")
weight_card = ComboBoxSettingCard(
FluentIcon.WEIGHT,
"무게",
"배송 상품의 무게를 입력하세요",
customWidget=self.weight_input,
parent=card_group
)
# 지역 선택
self.region_input = LineEdit(self.shipping_calc_tab)
self.region_input.setPlaceholderText("배송 지역")
region_card = ComboBoxSettingCard(
FluentIcon.GLOBE,
"지역",
"배송 지역을 입력하세요",
customWidget=self.region_input,
parent=card_group
)
# 카드 그룹에 추가
card_group.addSettingCard(weight_card)
card_group.addSettingCard(region_card)
# 계산 버튼
self.calc_button = PrimaryPushButton("계산하기")
self.calc_button.clicked.connect(self.calculate_shipping)
# 결과 표시
self.result_label = QLabel("배송비: ")
# 레이아웃에 위젯 추가
layout.addWidget(card_group)
layout.addWidget(self.calc_button)
layout.addWidget(self.result_label)
layout.addStretch()
def setup_forbidden_words_tab(self):
layout = QVBoxLayout(self.forbidden_words_tab)
# 설정 카드 그룹
card_group = SettingCardGroup("금지어 관리", self.forbidden_words_tab)
# 금지어 입력
self.word_input = LineEdit(self.forbidden_words_tab)
self.word_input.setPlaceholderText("금지어 입력")
word_card = ComboBoxSettingCard(
FluentIcon.REMOVE,
"금지어",
"추가할 금지어를 입력하세요. 콤마 또는 공백으로 구분하여 여러 개 입력 가능합니다.",
customWidget=self.word_input,
parent=card_group
)
card_group.addSettingCard(word_card)
# 추가 버튼
self.add_button = PrimaryPushButton("추가")
self.add_button.clicked.connect(self.add_forbidden_word)
# 금지어 목록
self.word_list = ListWidget(self.forbidden_words_tab)
# 삭제 버튼
self.delete_button = PushButton("선택 삭제")
self.delete_button.setIcon(FluentIcon.DELETE)
self.delete_button.clicked.connect(self.delete_forbidden_word)
# 금지어 목록 로드
if self.forbidden_words:
self.load_forbidden_words()
# 레이아웃에 위젯 추가
layout.addWidget(card_group)
layout.addWidget(self.add_button)
layout.addWidget(self.word_list)
layout.addWidget(self.delete_button)
def setup_category_tab(self):
layout = QVBoxLayout(self.category_tab)
# 설정 카드 그룹
card_group = SettingCardGroup("카테고리 관리", self.category_tab)
# 카테고리 입력
self.category_input = LineEdit(self.category_tab)
self.category_input.setPlaceholderText("카테고리 입력")
category_card = ComboBoxSettingCard(
FluentIcon.FOLDER,
"카테고리",
"추가할 카테고리를 입력하세요",
customWidget=self.category_input,
parent=card_group
)
card_group.addSettingCard(category_card)
# 추가 버튼
self.add_cat_button = PrimaryPushButton("추가")
self.add_cat_button.clicked.connect(self.add_category)
# 카테고리 목록
self.category_list = ListWidget(self.category_tab)
# 삭제 버튼
self.delete_cat_button = PushButton("선택 삭제")
self.delete_cat_button.setIcon(FluentIcon.DELETE)
self.delete_cat_button.clicked.connect(self.delete_category)
# 카테고리 목록 로드
if self.category_manager:
self.load_categories()
# 레이아웃에 위젯 추가
layout.addWidget(card_group)
layout.addWidget(self.add_cat_button)
layout.addWidget(self.category_list)
layout.addWidget(self.delete_cat_button)
def setup_log_tab(self):
layout = QVBoxLayout(self.log_tab)
# 설정 카드 그룹
card_group = SettingCardGroup("로그 관리", self.log_tab)
card_group.addSettingCard(SwitchSettingCard(
FluentIcon.HISTORY,
"자동 저장",
"로그를 자동으로 파일에 저장합니다",
True,
parent=card_group
))
# 로그 표시 영역
self.log_text = TextEdit(self.log_tab)
self.log_text.setReadOnly(True)
# 로그 정리 버튼
self.clear_button = PushButton("로그 정리")
self.clear_button.setIcon(FluentIcon.CLEAR)
self.clear_button.clicked.connect(self.clear_logs)
# 레이아웃에 위젯 추가
layout.addWidget(card_group)
layout.addWidget(self.log_text)
layout.addWidget(self.clear_button)
def setup_xls_filter_tab(self):
layout = QVBoxLayout(self.xls_filter_tab)
# 설정 카드 그룹
card_group = SettingCardGroup("엑셀 필터링", self.xls_filter_tab)
card_text = "엑셀 파일에서 상품 정보를 추출하고 금지어/카테고리를 필터링합니다."
info_card = SimpleCardWidget(FluentIcon.FILTER, "엑셀 필터링", card_text, self.xls_filter_tab)
info_card.setFixedHeight(120)
# 엑셀 필터링 버튼
self.filter_button = PrimaryPushButton("엑셀 필터링 실행")
self.filter_button.setIcon(FluentIcon.FILTER)
self.filter_button.clicked.connect(self.run_xls_filter)
# 레이아웃에 위젯 추가
layout.addWidget(card_group)
layout.addWidget(info_card)
layout.addWidget(self.filter_button)
layout.addStretch()
def calculate_shipping(self):
weight = self.weight_input.value()
region = self.region_input.text()
if not region:
self.show_info_bar("경고", "지역을 입력해주세요", InfoBarPosition.TOP, True)
self.status_changed.emit("무게와 지역을 입력해주세요.")
return
try:
# 여기에서 실제 배송비 계산 로직을 구현
shipping_cost = weight * 2500 # 예시 계산 로직
self.result_label.setText(f"배송비: {shipping_cost:,}")
self.status_changed.emit(f"배송비 계산 완료: {shipping_cost:,}")
self.show_info_bar("완료", f"배송비 계산 완료: {shipping_cost:,}", InfoBarPosition.BOTTOM_RIGHT)
except ValueError:
self.show_info_bar("오류", "무게는 숫자로 입력해주세요.", InfoBarPosition.TOP, True)
self.status_changed.emit("무게는 숫자로 입력해주세요.")
def show_info_bar(self, title, content, position=InfoBarPosition.TOP, is_error=False):
"""정보 바 표시"""
if is_error:
InfoBar.error(
title=title,
content=content,
parent=self,
position=position,
duration=3000
)
else:
InfoBar.success(
title=title,
content=content,
parent=self,
position=position,
duration=3000
)
def load_forbidden_words(self):
"""금지어 목록 로드"""
if self.logger:
self.logger.debug("금지어 목록 로드 시작")
words = self.forbidden_words.get_all_words()
self.word_list.clear()
for word in words:
self.word_list.addItem(word)
if self.logger:
self.logger.debug(f"금지어 {len(words)}개 로드 완료")
def add_forbidden_word(self):
word = self.word_input.text()
if word:
if self.forbidden_words:
self.forbidden_words.add_word(word)
self.status_changed.emit(f"금지어 '{word}' 추가됨")
self.show_info_bar("추가 완료", f"금지어 '{word}' 추가됨", InfoBarPosition.BOTTOM_RIGHT)
self.word_list.addItem(word)
self.word_input.clear()
def delete_forbidden_word(self):
current_item = self.word_list.currentItem()
if current_item:
word = current_item.text()
if self.forbidden_words:
self.forbidden_words.remove_word(word)
self.status_changed.emit(f"금지어 '{word}' 삭제됨")
self.show_info_bar("삭제 완료", f"금지어 '{word}' 삭제됨", InfoBarPosition.BOTTOM_RIGHT)
self.word_list.takeItem(self.word_list.row(current_item))
def load_categories(self):
"""카테고리 목록 로드"""
if self.logger:
self.logger.debug("카테고리 목록 로드 시작")
categories = self.category_manager.get_all_categories()
self.category_list.clear()
for category in categories:
self.category_list.addItem(category)
if self.logger:
self.logger.debug(f"카테고리 {len(categories)}개 로드 완료")
def add_category(self):
category = self.category_input.text()
if category:
if self.category_manager:
self.category_manager.add_category(category)
self.status_changed.emit(f"카테고리 '{category}' 추가됨")
self.show_info_bar("추가 완료", f"카테고리 '{category}' 추가됨", InfoBarPosition.BOTTOM_RIGHT)
self.category_list.addItem(category)
self.category_input.clear()
def delete_category(self):
current_item = self.category_list.currentItem()
if current_item:
category = current_item.text()
if self.category_manager:
self.category_manager.remove_category(category)
self.status_changed.emit(f"카테고리 '{category}' 삭제됨")
self.show_info_bar("삭제 완료", f"카테고리 '{category}' 삭제됨", InfoBarPosition.BOTTOM_RIGHT)
self.category_list.takeItem(self.category_list.row(current_item))
def clear_logs(self):
self.log_text.clear()
self.status_changed.emit("로그가 정리되었습니다.")
self.show_info_bar("완료", "로그가 정리되었습니다", InfoBarPosition.BOTTOM_RIGHT)
def run_xls_filter(self):
if self.logger:
self.logger.info("엑셀 필터링 다이얼로그 실행")
# 다이얼로그에 필요한 관리자 객체 전달
dialog = XlsFilterDialog(
parent=self,
thread_pool=self.thread_pool,
logger=self.logger,
forbidden_words=self.forbidden_words,
category_manager=self.category_manager
)
dialog.status_changed.connect(self.status_changed.emit)
dialog.exec()