feat: 초기 프로젝트 구조 추가
This commit is contained in:
156
main.py
Normal file
156
main.py
Normal file
@@ -0,0 +1,156 @@
|
||||
# 엔트리포인트 — 스플래시 화면 표시 후 백그라운드 초기화, GUI 실행
|
||||
import multiprocessing
|
||||
import sys
|
||||
|
||||
from logger import setup_logging, teardown_logging
|
||||
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
from PyQt5.QtGui import QIcon
|
||||
|
||||
from utils.path_helper import get_path
|
||||
from gui.main_window import MainWindow
|
||||
from gui.splash_screen import SplashScreen, InitWorker
|
||||
|
||||
ICON_PATH = get_path("assets", "images", "ant_logo.png")
|
||||
|
||||
|
||||
def _apply_windows_taskbar_icon(app_id: str = "ant.vision.inspection.1.0"):
|
||||
if sys.platform != "win32":
|
||||
return
|
||||
try:
|
||||
import ctypes
|
||||
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(app_id)
|
||||
except Exception as e:
|
||||
print(f"[main] AppUserModelID 설정 실패: {e}")
|
||||
|
||||
|
||||
def main():
|
||||
# setup_logging() must be called inside main(), not at module level.
|
||||
# On Windows, multiprocessing spawns subprocesses that re-import __main__,
|
||||
# and module-level setup_logging() would corrupt the log file and replace
|
||||
# builtins.print in every worker process.
|
||||
setup_logging()
|
||||
|
||||
_apply_windows_taskbar_icon()
|
||||
|
||||
app = QApplication(sys.argv)
|
||||
icon = QIcon(ICON_PATH)
|
||||
app.setWindowIcon(icon)
|
||||
app.setStyleSheet(_DARK_STYLE)
|
||||
|
||||
splash = SplashScreen()
|
||||
splash.show()
|
||||
QApplication.processEvents()
|
||||
|
||||
worker = InitWorker()
|
||||
worker.progress.connect(splash.update_progress)
|
||||
|
||||
def on_finished(results):
|
||||
window = MainWindow(
|
||||
results["insight"],
|
||||
results["basler"],
|
||||
results["config"],
|
||||
plc_client=results.get("plc"),
|
||||
)
|
||||
window.setWindowIcon(icon)
|
||||
window.show()
|
||||
splash.close()
|
||||
|
||||
def cleanup():
|
||||
results["insight"].disconnect()
|
||||
results["basler"].disconnect()
|
||||
if results["db"].is_connected():
|
||||
results["db"].disconnect()
|
||||
plc = results.get("plc")
|
||||
if plc and plc.is_connected():
|
||||
plc.disconnect()
|
||||
|
||||
app.aboutToQuit.connect(cleanup)
|
||||
|
||||
worker.finished.connect(on_finished)
|
||||
worker.start()
|
||||
|
||||
try:
|
||||
ret = app.exec_()
|
||||
finally:
|
||||
|
||||
teardown_logging()
|
||||
|
||||
sys.exit(ret)
|
||||
|
||||
|
||||
_DARK_STYLE = """
|
||||
QWidget {
|
||||
background-color: #1a1a1a;
|
||||
color: #ffffff;
|
||||
font-size: 14px;
|
||||
}
|
||||
QGroupBox {
|
||||
background-color: #222222;
|
||||
border: 1px solid #444444;
|
||||
border-radius: 6px;
|
||||
margin-top: 14px;
|
||||
padding: 10px 8px 8px 8px;
|
||||
}
|
||||
QGroupBox::title {
|
||||
subcontrol-origin: margin;
|
||||
left: 10px;
|
||||
padding: 0 4px;
|
||||
color: #aaaaaa;
|
||||
}
|
||||
QPushButton {
|
||||
background-color: #2e2e2e;
|
||||
color: #ffffff;
|
||||
border: 1px solid #555555;
|
||||
border-radius: 4px;
|
||||
min-height: 56px;
|
||||
padding: 0 20px;
|
||||
font-size: 14px;
|
||||
}
|
||||
QPushButton:hover { background-color: #3a3a3a; }
|
||||
QPushButton:pressed { background-color: #1e1e1e; }
|
||||
QPushButton:checked { background-color: #0055cc; border-color: #0077ff; }
|
||||
QPushButton:disabled { color: #666666; }
|
||||
QLineEdit, QSpinBox, QDoubleSpinBox {
|
||||
background-color: #2a2a2a;
|
||||
color: #ffffff;
|
||||
border: 1px solid #555555;
|
||||
border-radius: 4px;
|
||||
padding: 6px 8px;
|
||||
min-height: 38px;
|
||||
}
|
||||
QLabel { color: #ffffff; }
|
||||
QListWidget {
|
||||
background-color: #222222;
|
||||
color: #ffffff;
|
||||
border: 1px solid #444444;
|
||||
outline: none;
|
||||
}
|
||||
QListWidget::item:selected { background-color: #0055cc; }
|
||||
QProgressBar {
|
||||
background-color: #2a2a2a;
|
||||
border: 1px solid #555555;
|
||||
border-radius: 4px;
|
||||
text-align: center;
|
||||
min-height: 22px;
|
||||
}
|
||||
QProgressBar::chunk { background-color: #0055cc; border-radius: 4px; }
|
||||
QCheckBox { min-height: 38px; }
|
||||
QCheckBox::indicator { width: 22px; height: 22px; }
|
||||
QScrollBar:vertical {
|
||||
background: #2a2a2a;
|
||||
width: 10px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
QScrollBar::handle:vertical {
|
||||
background: #555555;
|
||||
border-radius: 5px;
|
||||
min-height: 30px;
|
||||
}
|
||||
QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical { height: 0; }
|
||||
"""
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
multiprocessing.freeze_support()
|
||||
main()
|
||||
Reference in New Issue
Block a user