239 lines
7.3 KiB
Python
239 lines
7.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
섹션 패널 모듈
|
|
지시, 고장, 작업, 기타 섹션을 탭으로 관리하는 패널입니다.
|
|
"""
|
|
|
|
from PySide6.QtWidgets import (
|
|
QWidget, QVBoxLayout, QTabWidget, QTabBar
|
|
)
|
|
from PySide6.QtCore import Qt, Signal
|
|
from PySide6.QtGui import QFont
|
|
|
|
from ui.base.base_widget import BaseWidget
|
|
from ui.sections.instruction_section import InstructionSection
|
|
from ui.sections.fault_section import FaultSection
|
|
from ui.sections.work_section import WorkSection
|
|
from ui.sections.misc_section import MiscSection
|
|
from core.config import ConfigManager
|
|
from core.signals import GlobalSignals
|
|
from core.logger import get_logger
|
|
|
|
logger = get_logger(__name__)
|
|
|
|
|
|
class SectionPanel(BaseWidget):
|
|
"""
|
|
섹션 패널 위젯
|
|
|
|
지시, 고장, 작업, 기타 섹션을 탭으로 관리합니다.
|
|
|
|
Signals:
|
|
section_changed: 섹션 변경 시그널 (섹션 이름)
|
|
|
|
Examples:
|
|
>>> panel = SectionPanel()
|
|
>>> panel.set_current_section("fault")
|
|
"""
|
|
|
|
section_changed = Signal(str)
|
|
|
|
# 섹션 정의
|
|
SECTIONS = {
|
|
"instruction": {"name": "지시", "icon": "📋"},
|
|
"fault": {"name": "고장", "icon": "⚠️"},
|
|
"work": {"name": "작업", "icon": "🔧"},
|
|
"misc": {"name": "기타", "icon": "📝"},
|
|
}
|
|
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent)
|
|
|
|
self._current_section = "instruction"
|
|
self._sections = {}
|
|
|
|
self.setMinimumWidth(400)
|
|
|
|
self._setup_ui()
|
|
self._connect_signals()
|
|
|
|
logger.info("섹션 패널 초기화 완료")
|
|
|
|
def _setup_ui(self):
|
|
"""UI 설정"""
|
|
layout = QVBoxLayout(self)
|
|
layout.setContentsMargins(16, 16, 16, 16)
|
|
layout.setSpacing(0)
|
|
|
|
# 탭 위젯
|
|
self.tab_widget = QTabWidget()
|
|
self.tab_widget.setObjectName("sectionTabWidget")
|
|
self.tab_widget.setFont(QFont("GmarketSans", 13))
|
|
self.tab_widget.setDocumentMode(True)
|
|
|
|
# 섹션 추가
|
|
self._create_sections()
|
|
|
|
# 탭 변경 시그널
|
|
self.tab_widget.currentChanged.connect(self._on_tab_changed)
|
|
|
|
layout.addWidget(self.tab_widget)
|
|
|
|
# 스타일 적용
|
|
self._apply_style()
|
|
|
|
def _create_sections(self):
|
|
"""섹션 생성"""
|
|
# 지시 섹션
|
|
self.instruction_section = InstructionSection()
|
|
self._sections["instruction"] = self.instruction_section
|
|
self.tab_widget.addTab(
|
|
self.instruction_section,
|
|
f"{self.SECTIONS['instruction']['icon']} {self.SECTIONS['instruction']['name']}"
|
|
)
|
|
|
|
# 고장 섹션
|
|
self.fault_section = FaultSection()
|
|
self._sections["fault"] = self.fault_section
|
|
self.tab_widget.addTab(
|
|
self.fault_section,
|
|
f"{self.SECTIONS['fault']['icon']} {self.SECTIONS['fault']['name']}"
|
|
)
|
|
|
|
# 작업 섹션
|
|
self.work_section = WorkSection()
|
|
self._sections["work"] = self.work_section
|
|
self.tab_widget.addTab(
|
|
self.work_section,
|
|
f"{self.SECTIONS['work']['icon']} {self.SECTIONS['work']['name']}"
|
|
)
|
|
|
|
# 기타 섹션
|
|
self.misc_section = MiscSection()
|
|
self._sections["misc"] = self.misc_section
|
|
self.tab_widget.addTab(
|
|
self.misc_section,
|
|
f"{self.SECTIONS['misc']['icon']} {self.SECTIONS['misc']['name']}"
|
|
)
|
|
|
|
def _apply_style(self):
|
|
"""스타일 적용"""
|
|
theme = self.config.theme
|
|
|
|
if theme == 'dark':
|
|
bg = "#0f172a"
|
|
tab_bg = "#1e293b"
|
|
tab_selected = "#3b82f6"
|
|
tab_text = "#94a3b8"
|
|
tab_text_selected = "#ffffff"
|
|
border = "#334155"
|
|
else:
|
|
bg = "#f8fafc"
|
|
tab_bg = "#ffffff"
|
|
tab_selected = "#3b82f6"
|
|
tab_text = "#64748b"
|
|
tab_text_selected = "#ffffff"
|
|
border = "#e2e8f0"
|
|
|
|
self.setStyleSheet(f"""
|
|
SectionPanel {{
|
|
background-color: {bg};
|
|
}}
|
|
|
|
#sectionTabWidget {{
|
|
background-color: {bg};
|
|
}}
|
|
|
|
#sectionTabWidget::pane {{
|
|
background-color: {tab_bg};
|
|
border: 1px solid {border};
|
|
border-radius: 12px;
|
|
border-top-left-radius: 0;
|
|
padding: 8px;
|
|
}}
|
|
|
|
#sectionTabWidget QTabBar::tab {{
|
|
background-color: {tab_bg};
|
|
color: {tab_text};
|
|
border: 1px solid {border};
|
|
border-bottom: none;
|
|
padding: 10px 20px;
|
|
margin-right: 4px;
|
|
border-top-left-radius: 8px;
|
|
border-top-right-radius: 8px;
|
|
font-weight: 500;
|
|
}}
|
|
|
|
#sectionTabWidget QTabBar::tab:selected {{
|
|
background-color: {tab_selected};
|
|
color: {tab_text_selected};
|
|
border-color: {tab_selected};
|
|
font-weight: bold;
|
|
}}
|
|
|
|
#sectionTabWidget QTabBar::tab:hover:!selected {{
|
|
background-color: {border};
|
|
}}
|
|
""")
|
|
|
|
def _connect_signals(self):
|
|
"""시그널 연결"""
|
|
self.signals.section_tab_changed.connect(self._on_section_signal)
|
|
|
|
def _on_tab_changed(self, index: int):
|
|
"""탭 변경"""
|
|
section_keys = list(self.SECTIONS.keys())
|
|
if 0 <= index < len(section_keys):
|
|
self._current_section = section_keys[index]
|
|
self.section_changed.emit(self._current_section)
|
|
self.signals.section_tab_changed.emit(self._current_section)
|
|
logger.debug(f"섹션 변경: {self._current_section}")
|
|
|
|
def _on_section_signal(self, section: str):
|
|
"""외부 섹션 변경 시그널"""
|
|
self.set_current_section(section)
|
|
|
|
def set_current_section(self, section: str):
|
|
"""
|
|
현재 섹션 설정
|
|
|
|
Args:
|
|
section: 섹션 키 (instruction, fault, work, misc)
|
|
"""
|
|
section_keys = list(self.SECTIONS.keys())
|
|
if section in section_keys:
|
|
index = section_keys.index(section)
|
|
self.tab_widget.setCurrentIndex(index)
|
|
|
|
def get_current_section(self) -> str:
|
|
"""현재 섹션 반환"""
|
|
return self._current_section
|
|
|
|
def get_section(self, section: str) -> QWidget:
|
|
"""
|
|
섹션 위젯 반환
|
|
|
|
Args:
|
|
section: 섹션 키
|
|
|
|
Returns:
|
|
섹션 위젯
|
|
"""
|
|
return self._sections.get(section)
|
|
|
|
def refresh_data(self):
|
|
"""모든 섹션 데이터 새로고침"""
|
|
for section in self._sections.values():
|
|
if hasattr(section, 'refresh_data'):
|
|
section.refresh_data()
|
|
|
|
def refresh_all_sections(self):
|
|
"""모든 섹션 새로고침 (필드 표시 설정 포함)"""
|
|
for section in self._sections.values():
|
|
if hasattr(section, '_load_field_visibility'):
|
|
section._load_field_visibility()
|
|
if hasattr(section, 'refresh_data'):
|
|
section.refresh_data()
|
|
|
|
|