# -*- coding: utf-8 -*- """ 상태바 모듈 화면 하단의 상태 표시 바입니다. 접속자 정보, DB 상태, 동기화 상태, 버전 정보 등을 표시합니다. """ from datetime import datetime from PySide6.QtWidgets import ( QWidget, QHBoxLayout, QLabel, QFrame, QProgressBar ) from PySide6.QtCore import Qt, Signal, QTimer from PySide6.QtGui import QFont from ui.base.base_widget import BaseWidget from core.config import ConfigManager from core.signals import GlobalSignals from core.constants import APP_VERSION from core.logger import get_logger logger = get_logger(__name__) class StatusBar(BaseWidget): """ 상태바 위젯 화면 하단 10% 영역에 표시되는 상태 바입니다. 접속자, DB 상태, 마지막 동기화, 버전 정보 등을 포함합니다. Examples: >>> status_bar = StatusBar() >>> status_bar.set_user_info("홍길동", "검수팀") """ def __init__(self, parent=None): super().__init__(parent) self._user_name = "" self._user_department = "" self._db_status = "정상" self._sync_time = None self._message = "" self._message_timer = QTimer() self._message_timer.setSingleShot(True) self._message_timer.timeout.connect(self._clear_message) self._setup_ui() self._connect_signals() logger.info("상태바 초기화 완료") def _setup_ui(self): """UI 설정""" layout = QHBoxLayout(self) layout.setContentsMargins(24, 8, 24, 8) layout.setSpacing(16) # 사용자 정보 self._create_user_section(layout) # 구분선 self._add_separator(layout) # DB 상태 self._create_db_section(layout) # 구분선 self._add_separator(layout) # 동기화 상태 self._create_sync_section(layout) # 늘어남 영역 layout.addStretch() # 상태 메시지 self._create_message_section(layout) # 늘어남 영역 layout.addStretch() # 프로그레스바 (숨김) self._create_progress_section(layout) # 구분선 self._add_separator(layout) # 버전 정보 self._create_version_section(layout) # 스타일 적용 self._apply_style() def _create_user_section(self, layout: QHBoxLayout): """사용자 섹션 생성""" self.user_icon = QLabel("👤") self.user_icon.setFont(QFont("Segoe UI Emoji", 14)) self.user_label = QLabel("로그인 필요") self.user_label.setObjectName("userLabel") self.user_label.setFont(QFont("GmarketSans", 12)) layout.addWidget(self.user_icon) layout.addWidget(self.user_label) def _create_db_section(self, layout: QHBoxLayout): """DB 상태 섹션 생성""" self.db_icon = QLabel("🗄️") self.db_icon.setFont(QFont("Segoe UI Emoji", 14)) self.db_label = QLabel("DB 상태: 정상") self.db_label.setObjectName("dbLabel") self.db_label.setFont(QFont("GmarketSans", 12)) layout.addWidget(self.db_icon) layout.addWidget(self.db_label) def _create_sync_section(self, layout: QHBoxLayout): """동기화 상태 섹션 생성""" self.sync_icon = QLabel("🔄") self.sync_icon.setFont(QFont("Segoe UI Emoji", 14)) self.sync_label = QLabel("동기화: 로컬 전용") self.sync_label.setObjectName("syncLabel") self.sync_label.setFont(QFont("GmarketSans", 12)) layout.addWidget(self.sync_icon) layout.addWidget(self.sync_label) def _create_message_section(self, layout: QHBoxLayout): """상태 메시지 섹션 생성""" self.message_label = QLabel("") self.message_label.setObjectName("messageLabel") self.message_label.setFont(QFont("GmarketSans", 12)) self.message_label.setAlignment(Qt.AlignCenter) layout.addWidget(self.message_label) def _create_progress_section(self, layout: QHBoxLayout): """프로그레스바 섹션 생성""" self.progress_bar = QProgressBar() self.progress_bar.setObjectName("progressBar") self.progress_bar.setFixedWidth(150) self.progress_bar.setFixedHeight(6) self.progress_bar.setTextVisible(False) self.progress_bar.hide() layout.addWidget(self.progress_bar) def _create_version_section(self, layout: QHBoxLayout): """버전 섹션 생성""" self.version_label = QLabel(f"v{APP_VERSION}") self.version_label.setObjectName("versionLabel") self.version_label.setFont(QFont("GmarketSans", 11)) layout.addWidget(self.version_label) def _add_separator(self, layout: QHBoxLayout): """구분선 추가""" separator = QFrame() separator.setFrameShape(QFrame.VLine) separator.setObjectName("separator") layout.addWidget(separator) def _apply_style(self): """스타일 적용""" theme = self.config.theme if theme == 'dark': bg = "#0f172a" text = "#94a3b8" separator = "#334155" success = "#22c55e" warning = "#f59e0b" error = "#ef4444" progress_bg = "#334155" progress_fill = "#3b82f6" else: bg = "#f8fafc" text = "#64748b" separator = "#e2e8f0" success = "#22c55e" warning = "#f59e0b" error = "#ef4444" progress_bg = "#e2e8f0" progress_fill = "#3b82f6" self.setStyleSheet(f""" StatusBar {{ background-color: {bg}; border-top: 1px solid {separator}; }} QLabel {{ color: {text}; }} #separator {{ color: {separator}; }} #progressBar {{ background-color: {progress_bg}; border: none; border-radius: 3px; }} #progressBar::chunk {{ background-color: {progress_fill}; border-radius: 3px; }} """) def _connect_signals(self): """시그널 연결""" self.signals.user_logged_in.connect(self._on_user_logged_in) self.signals.user_logged_out.connect(self._on_user_logged_out) self.signals.sync_completed.connect(self._on_sync_completed) self.signals.sync_error.connect(self._on_sync_error) self.signals.status_message.connect(self.show_message) self.signals.update_progress.connect(self._on_update_progress) # ======================================================================== # 공개 메서드 # ======================================================================== def set_user_info(self, name: str, department: str): """ 사용자 정보 설정 Args: name: 사용자 이름 department: 부서명 """ self._user_name = name self._user_department = department self.user_label.setText(f"{name} ({department})") def set_db_status(self, status: str, is_error: bool = False): """ DB 상태 설정 Args: status: 상태 텍스트 is_error: 오류 여부 """ self._db_status = status self.db_label.setText(f"DB 상태: {status}") if is_error: self.db_icon.setText("⚠️") else: self.db_icon.setText("🗄️") def set_sync_time(self, sync_time: datetime = None): """ 동기화 시간 설정 Args: sync_time: 동기화 시간 """ self._sync_time = sync_time if sync_time: time_str = sync_time.strftime("%H:%M") self.sync_label.setText(f"마지막 동기화: {time_str}") else: self.sync_label.setText("동기화: 로컬 전용") def show_message(self, message: str, timeout: int = 3000): """ 상태 메시지 표시 Args: message: 메시지 텍스트 timeout: 표시 시간 (ms) """ self._message = message self.message_label.setText(message) if timeout > 0: self._message_timer.start(timeout) def _clear_message(self): """메시지 지우기""" self._message = "" self.message_label.setText("") def show_progress(self, value: int = -1): """ 프로그레스바 표시 Args: value: 진행률 (0-100), -1이면 무한 """ self.progress_bar.show() if value < 0: self.progress_bar.setRange(0, 0) # 무한 프로그레스 else: self.progress_bar.setRange(0, 100) self.progress_bar.setValue(value) def hide_progress(self): """프로그레스바 숨기기""" self.progress_bar.hide() # ======================================================================== # 시그널 핸들러 # ======================================================================== def _on_user_logged_in(self, user_id: int, username: str): """사용자 로그인""" # TODO: DB에서 사용자 정보 조회 self.set_user_info(username, "") def _on_user_logged_out(self): """사용자 로그아웃""" self._user_name = "" self._user_department = "" self.user_label.setText("로그인 필요") def _on_sync_completed(self): """동기화 완료""" self.set_sync_time(datetime.now()) self.show_message("동기화 완료", 2000) def _on_sync_error(self, error_msg: str): """동기화 오류""" self.sync_icon.setText("⚠️") self.show_message(f"동기화 오류: {error_msg}", 5000) def _on_update_progress(self, value: int): """업데이트 진행률""" if value >= 100: self.hide_progress() else: self.show_progress(value)