From f5751460e3a33d98470f00bd88ce7bfad221d2f2 Mon Sep 17 00:00:00 2001 From: KINDNICK Date: Thu, 4 Jun 2026 19:21:49 +0900 Subject: [PATCH] =?UTF-8?q?v2.11.2:=20=ED=86=B5=EA=B3=84=20=EC=B0=A8?= =?UTF-8?q?=ED=8A=B8=20frozen=20=EC=8B=A4=EC=A0=9C=20=EC=88=98=EC=A0=95(nu?= =?UTF-8?q?mpy=20=5Fmultiarray=5Ftests)=20+=20=EB=8F=84=EC=A0=84=EA=B3=BC?= =?UTF-8?q?=EC=A0=9C=20=EB=9D=BC=EC=9D=B4=ED=8A=B8=20=EA=B0=80=EB=8F=85?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - fix: frozen main.exe에서 numpy.core._multiarray_tests 누락으로 matplotlib import 실패 → 차트 폴백. spec에 hiddenimport 추가 + numpy.testing 제외 제거 (디버그 로그로 원인 확인) - fix: 도전과제 라이트 테마 헤더 숫자/배지/진행 텍스트/바 대비 개선 Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.md | 10 ++++++++++ core/version.py | 2 +- main.spec | 4 +++- ui/achievements_view.py | 36 +++++++++++++++++++++--------------- 4 files changed, 35 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ac19cf..440bec2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). +## [2.11.2] — 2026-06-04 + +### Fixed +- **통계 차트가 빌드(main.exe)에서 안 뜨던 진짜 원인** — frozen 빌드에서 numpy C-확장 + `numpy.core._multiarray_tests`가 누락(`numpy.testing` 제외의 영향)되어 matplotlib import가 + `ModuleNotFoundError`로 실패 → "matplotlib 필요" 폴백. `main.spec`에 해당 모듈 hiddenimport + 추가 + `numpy.testing` 제외 제거. (디버그 로그로 원인 확인: chart_widget이 실패 사유를 기록) +- **도전과제 라이트 테마 가독성** — 헤더 강조 숫자/등급 배지/진행 숫자/진행 바를 라이트에서 + 대비 높은 색으로 조정 (다크는 기존 비비드 색 유지). + ## [2.11.1] — 2026-06-04 ### Fixed diff --git a/core/version.py b/core/version.py index 7db5bba..4f4ddc5 100644 --- a/core/version.py +++ b/core/version.py @@ -4,4 +4,4 @@ 릴리스 시 이 값을 올린 후 git tag → push. CHANGELOG.md의 최상단 항목과 일치시킬 것. """ -__version__ = '2.11.1' +__version__ = '2.11.2' diff --git a/main.spec b/main.spec index 69fd201..45ac162 100644 --- a/main.spec +++ b/main.spec @@ -36,11 +36,13 @@ a = Analysis( 'matplotlib.backends.backend_qt5agg', 'PyQt5.QtSvg', 'PyQt5.sip', # matplotlib qt_compat가 sip 사용 + 'numpy.core._multiarray_tests', # numpy import 체인이 참조 (frozen 차트 깨짐 방지) ], hookspath=[], hooksconfig={}, runtime_hooks=[], - excludes=['pandas', 'numpy.testing', 'PyQt5.QtWebEngineWidgets'], + # numpy.testing 제외 금지 — numpy.core._multiarray_tests 참조가 끊겨 matplotlib import 실패함 + excludes=['pandas', 'PyQt5.QtWebEngineWidgets'], noarchive=False, optimize=0, ) diff --git a/ui/achievements_view.py b/ui/achievements_view.py index 3d4e832..cafb0af 100644 --- a/ui/achievements_view.py +++ b/ui/achievements_view.py @@ -165,7 +165,13 @@ class AchievementsView(QDialog): num_row = QHBoxLayout() num_row.setSpacing(24) - big = QLabel(f"{stats['earned']}" + # 헤더 강조 숫자색 — 다크는 비비드, 라이트는 동일 색조 진하게(가독성) + if _is_dark(): + c_earned, c_secret, c_pct = '#ffd24a', '#ff90b8', '#4adef0' + else: + c_earned, c_secret, c_pct = '#C8950A', '#C2185B', '#0E7490' + + big = QLabel(f"{stats['earned']}" f" / {stats['total']}") big.setTextFormat(Qt.RichText) num_row.addWidget(big) @@ -178,7 +184,7 @@ class AchievementsView(QDialog): secret_lbl = QLabel( f"
" f"🌑 시크릿
" - f"" + f"" f"{stats['secret_earned']}" f" / {stats['secret_total']}" f"
" @@ -191,7 +197,7 @@ class AchievementsView(QDialog): pct_lbl = QLabel( f"
" f"달성률
" - f"" + f"" f"{pct:.1f}%
" ) pct_lbl.setTextFormat(Qt.RichText) @@ -207,17 +213,17 @@ class AchievementsView(QDialog): bar.setTextVisible(False) bar.setMinimumHeight(8) bar.setMaximumHeight(8) - bar.setStyleSheet(""" - QProgressBar { - background: #1a1a26; + bar.setStyleSheet(f""" + QProgressBar {{ + background: {tc('panel2')}; border: none; border-radius: 4px; - } - QProgressBar::chunk { + }} + QProgressBar::chunk {{ background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0 #4adef0, stop:0.5 #6b9eff, stop:1 #ff90b8); border-radius: 4px; - } + }} """) layout.addWidget(bar) @@ -343,8 +349,8 @@ class AchievementsView(QDialog): cat_label = QLabel(f" {theme['label']} {theme['name']} · {cat_text} ") cat_label.setStyleSheet( f"font-size: 8.5pt; " - f"color: {theme['border_strong']}; " - f"background: rgba(255,255,255,0.05); " + f"color: {theme['border_strong'] if _is_dark() else tc('text_dim')}; " + f"background: {'rgba(255,255,255,0.05)' if _is_dark() else tc('panel2')}; " f"border: 1px solid {theme['border']}; " f"border-radius: 8px; " f"padding: 1px 4px;" @@ -377,9 +383,9 @@ class AchievementsView(QDialog): if is_earned: earned = QLabel(f" ✓ {item['earned_date']} 달성 ") earned.setStyleSheet( - f"color: {theme['border_strong']}; " + f"color: {theme['border_strong'] if _is_dark() else tc('text')}; " f"font-weight: bold; font-size: 9.5pt; " - f"background: rgba(255,255,255,0.08); " + f"background: {'rgba(255,255,255,0.08)' if _is_dark() else tc('panel2')}; " f"border: 1px solid {theme['border']}; " f"border-radius: 6px; padding: 4px 8px;" ) @@ -405,7 +411,7 @@ class AchievementsView(QDialog): pb.setMaximumHeight(10) pb.setStyleSheet(f""" QProgressBar {{ - background: rgba(0,0,0,0.4); + background: {'rgba(0,0,0,0.4)' if _is_dark() else tc('panel2')}; border: none; border-radius: 5px; }} @@ -419,7 +425,7 @@ class AchievementsView(QDialog): num = QLabel(f"{progress} / {target}") num.setStyleSheet( - f"color: {theme['border_strong']}; font-size: 9pt; " + f"color: {theme['border_strong'] if _is_dark() else tc('text_dim')}; font-size: 9pt; " f"font-weight: bold; background: transparent; border: none;" ) num.setMinimumWidth(60)