feat: 초기 프로젝트 구조 추가

This commit is contained in:
Kim Min Jae
2026-06-10 16:18:41 +09:00
parent 5d985560c5
commit a48a4b5fe5
100 changed files with 10530 additions and 0 deletions

182
gui/splash_screen.py Normal file
View File

@@ -0,0 +1,182 @@
import json
import os
from PyQt5.QtWidgets import QWidget, QLabel, QProgressBar, QVBoxLayout, QApplication
from PyQt5.QtCore import Qt, QThread, pyqtSignal
from PyQt5.QtGui import QPainter, QPainterPath, QColor
class SplashScreen(QWidget):
def __init__(self):
super().__init__()
self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
self.setAttribute(Qt.WA_TranslucentBackground)
self.setFixedSize(500, 300)
screen = QApplication.primaryScreen().geometry()
self.move(
(screen.width() - self.width()) // 2,
(screen.height() - self.height()) // 2,
)
self._build_ui()
def _build_ui(self):
layout = QVBoxLayout(self)
layout.setContentsMargins(40, 40, 40, 30)
layout.setSpacing(0)
title = QLabel("리플렉터 검사 시스템")
title.setAlignment(Qt.AlignCenter)
title.setStyleSheet(
"color:#ffffff; font-size:22px; font-weight:bold; background:transparent;"
)
subtitle = QLabel("Reflector Inspection System")
subtitle.setAlignment(Qt.AlignCenter)
subtitle.setStyleSheet("color:#555555; font-size:12px; background:transparent;")
layout.addStretch(2)
layout.addWidget(title)
layout.addSpacing(6)
layout.addWidget(subtitle)
layout.addStretch(3)
self.status_label = QLabel("초기화 중...")
self.status_label.setAlignment(Qt.AlignCenter)
self.status_label.setStyleSheet(
"color:#888888; font-size:13px; background:transparent;"
)
layout.addWidget(self.status_label)
layout.addSpacing(10)
self.progress_bar = QProgressBar()
self.progress_bar.setRange(0, 100)
self.progress_bar.setValue(0)
self.progress_bar.setFixedHeight(6)
self.progress_bar.setTextVisible(False)
self.progress_bar.setStyleSheet("""
QProgressBar {
background: #2a2a2a;
border: none;
border-radius: 3px;
}
QProgressBar::chunk {
background: #1D9E75;
border-radius: 3px;
}
""")
layout.addWidget(self.progress_bar)
layout.addStretch(1)
version = QLabel("v1.0.0")
version.setAlignment(Qt.AlignCenter)
version.setStyleSheet("color:#333333; font-size:11px; background:transparent;")
layout.addWidget(version)
def update_progress(self, value: int, message: str):
self.progress_bar.setValue(value)
self.status_label.setText(message)
QApplication.processEvents()
def paintEvent(self, event):
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
path = QPainterPath()
path.addRoundedRect(0.0, 0.0, float(self.width()), float(self.height()), 12.0, 12.0)
painter.fillPath(path, QColor("#0d0d0d"))
class InitWorker(QThread):
progress = pyqtSignal(int, str) # (진행률, 메시지)
finished = pyqtSignal(object) # 초기화 결과 dict
def run(self):
from utils.path_helper import get_path
from camera.insight import InSightCamera
from camera.basler import BaslerCamera
from ai.detector import Detector
from db.sql_client import SQLClient
results = {}
# ── 1단계: 설정 로드 ──────────────────────────────────────────── #
self.progress.emit(10, "설정 불러오는 중...")
try:
with open(get_path("config.json"), encoding="utf-8") as f:
config = json.load(f)
except Exception as e:
print(f"[InitWorker] 설정 로드 실패: {e}")
config = {}
results["config"] = config
# ── 2단계: 코그넥스 카메라 ────────────────────────────────────── #
self.progress.emit(25, "코그넥스 카메라 연결 중...")
insight = InSightCamera()
try:
cognex_cfg = config.get("cognex", {})
ip = cognex_cfg.get("ip", "")
port = cognex_cfg.get("port", 23)
if ip:
insight.connect(ip, port)
except Exception as e:
print(f"[InitWorker] 코그넥스 연결 실패: {e}")
results["insight"] = insight
# ── 3단계: Basler 카메라 ──────────────────────────────────────── #
self.progress.emit(45, "Basler 카메라 연결 중...")
basler = BaslerCamera()
try:
basler.connect()
except Exception as e:
print(f"[InitWorker] Basler 연결 실패: {e}")
results["basler"] = basler
# ── 4단계: AI 모델 로드 ───────────────────────────────────────── #
self.progress.emit(65, "AI 모델 로드 중...")
detector = Detector()
try:
from paths import resolve_path
model_path = config.get("ai", {}).get("model_path", "")
if model_path:
abs_path = resolve_path(model_path)
if abs_path and os.path.exists(abs_path):
detector.load_model(abs_path)
except Exception as e:
print(f"[InitWorker] AI 모델 로드 실패: {e}")
results["detector"] = detector
# ── 5단계: DB 연결 ────────────────────────────────────────────── #
self.progress.emit(80, "DB 연결 중...")
db_client = SQLClient()
try:
db_cfg = config.get("db", {})
if db_cfg.get("server"):
db_client.connect(
db_cfg["server"],
db_cfg["database"],
db_cfg["username"],
db_cfg["password"],
)
except Exception as e:
print(f"[InitWorker] DB 연결 실패: {e}")
results["db"] = db_client
# ── 6단계: PLC 연결 ───────────────────────────────────────────── #
self.progress.emit(92, "PLC 연결 중...")
plc_client = None
try:
from plc.plc_client import PLCClient
plc_cfg = config.get("plc", {})
ip = plc_cfg.get("ip", "").strip()
port = plc_cfg.get("port", 5010)
if ip:
client = PLCClient()
if client.connect(ip, port):
plc_client = client
except Exception as e:
print(f"[InitWorker] PLC 연결 실패: {e}")
results["plc"] = plc_client
# ── 완료 ──────────────────────────────────────────────────────── #
self.progress.emit(100, "시작 중...")
self.finished.emit(results)