- CLI 환경: onnxruntime, rembg 등 모든 라이브러리 정상 로딩 ✅
- GUI 환경: PyQt5 사용 시 DLL 로딩 실패 ❌
1
2
| ⚠️ AI 모델 실행 라이브러리 오류: DLL load failed while importing...
⚠️ 배경 제거 라이브러리 오류: DLL load failed while importing...
|
- OS: Windows 10/11
- Python: 3.8+
- 라이브러리: PyQt5, onnxruntime, rembg, scipy
- 패키지 관리: pip (가상환경)
1
2
3
| # 문제가 되는 순서
from PyQt5.QtWidgets import QApplication # PyQt5 먼저 로딩
import onnxruntime # ❌ DLL 로딩 실패
|
- Qt 라이브러리들을 로딩하면서 DLL 검색 경로 수정
- Windows API SetDllDirectory() 호출
- 시스템 PATH 환경변수 우선순위 변경
- 특정 DLL들의 로딩 방식 제한
1
2
3
4
5
6
| onnxruntime.dll
├── msvcp140.dll (Visual C++ Runtime)
├── vcruntime140.dll
├── concrt140.dll
├── onnxruntime_providers_shared.dll
└── 기타 CUDA/DirectML 관련 DLL들
|
- PyQt5 로딩 후 DLL 검색 경로가 변경되어 의존성 DLL들을 찾지 못함
- 특히 Visual C++ Redistributable 관련 DLL들의 로딩 순서 충돌
- 실행 파일과 같은 디렉토리
- 시스템 디렉토리 (System32)
- Windows 디렉토리
- 현재 디렉토리
- PATH 환경변수 디렉토리들
- Qt 라이브러리 디렉토리가 최우선으로 변경
- Python 패키지 디렉토리 우선순위 하락
- 결과: onnxruntime의 DLL들을 찾지 못함
1
2
3
4
5
| # ✅ 올바른 순서
import scipy # 1. 가장 안전한 라이브러리부터
import onnxruntime # 2. 무거운 라이브러리
import rembg # 3. 의존성이 있는 라이브러리
from PyQt5.QtWidgets import QApplication # 4. 마지막에 PyQt5
|
- DLL 경로 명시적 추가 Python 3.8+ Windows 전용 해결책:
1
2
3
4
5
6
7
8
| import os
import sys
# DLL 검색 경로에 Python 실행 파일 디렉토리 추가
if hasattr(os, 'add_dll_directory'):
python_dir = os.path.dirname(sys.executable)
if os.path.exists(python_dir):
os.add_dll_directory(python_dir)
|
일반적인 해결 패턴
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| # 범용적인 해결 패턴
import os
import sys
# 1. DLL 경로 추가 (Windows 전용)
if hasattr(os, 'add_dll_directory'):
python_dir = os.path.dirname(sys.executable)
if os.path.exists(python_dir):
os.add_dll_directory(python_dir)
# 2. 무거운 라이브러리들 미리 로딩
heavy_libs = []
for lib_name in ['scipy', 'onnxruntime', 'rembg']:
try:
exec(f'import {lib_name}')
heavy_libs.append(lib_name)
print(f'✅ {lib_name} 미리 로딩 성공')
except Exception as e:
print(f'⚠️ {lib_name} 미리 로딩 실패: {e}')
# 3. 마지막에 GUI 프레임워크 로딩
from PyQt5.QtWidgets import QApplication
|
이 분석이 ai 서비스 프로그램 개발에 도움이 되시길 바랍니다! 🚀
+추가)
1
2
3
4
5
| # requirements.txt
onnxruntime
scipy
rembg
PyQt5
|
import 순서때문에 fail 하는 예시
fail하는 cli 프로그램
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
| #!/usr/bin/env python3
"""
안전한 로딩 테스트 (CLI 전용)
"""
import time
import importlib
def check_basic_libraries():
print("🔄 Python 환경 확인 중...")
time.sleep(0.3)
print("📦 기본 라이브러리 확인 중...")
try:
import math
import os
import sys
print("✅ 기본 라이브러리 확인 완료")
return True
except Exception as e:
print(f"❌ 기본 라이브러리 확인 실패: {e}")
return False
def check_image_libraries():
print("📸 이미지 처리 라이브러리 확인 중...")
try:
from PIL import Image
import numpy as np
print("✅ 이미지 처리 라이브러리 확인 완료")
return True
except Exception as e:
print(f"❌ 이미지 처리 라이브러리 확인 실패: {e}")
return False
def check_gui_libraries():
print("🖥️ GUI 라이브러리 확인 중...")
try:
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QColor
print("✅ GUI 라이브러리 확인 완료")
return True
except Exception as e:
print(f"❌ GUI 라이브러리 확인 실패: {e}")
return False
def check_optional_libraries():
print("🔍 선택적 라이브러리 확인 중...")
optional_libs = [("scipy", "고급 수학 연산"), ("onnxruntime", "AI 모델 실행"), ("rembg", "배경 제거")]
available = []
for lib_name, description in optional_libs:
print(f"🔍 {description} 라이브러리 확인 중...")
try:
if lib_name == "onnxruntime":
import onnxruntime
providers = onnxruntime.get_available_providers()
print(f"✅ {description} 라이브러리 사용 가능 (Providers: {len(providers)}개)")
elif lib_name == "scipy":
import scipy
print(f"✅ {description} 라이브러리 사용 가능")
elif lib_name == "rembg":
import rembg
print(f"✅ {description} 라이브러리 사용 가능")
available.append(description)
except Exception as e:
print(f"⚠️ {description} 라이브러리 오류: {str(e)[:60]}...")
time.sleep(0.2)
return available
def main():
print("🚀 안전한 CLI 로딩 테스트 시작\n")
time.sleep(0.3)
ok1 = check_basic_libraries()
ok2 = check_image_libraries()
ok3 = check_gui_libraries()
available = check_optional_libraries() ## 늦게 로딩해서 실패.
print("\n🔍 최종 상태 확인 중...")
time.sleep(0.3)
if ok1 and ok2 and ok3:
print("🎉 초기화 완료!")
if available:
print(f"✅ 앱 준비 완료! 사용 가능한 선택적 기능: {len(available)}개")
else:
print("⚠️ 앱 준비 완료 (선택 기능 없음)")
else:
print("❌ 초기화 실패: 필수 라이브러리 중 일부가 누락되었습니다.")
print("🧪 테스트 완료!")
if __name__ == "__main__":
main()
|
fail하는 gui 프로그램
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
| #!/usr/bin/env python3
"""
안전한 로딩 화면 테스트 스크립트 (메인 스레드에서 무거운 라이브러리 먼저 로딩)
"""
import sys
import os
import time
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel, QProgressBar
from PyQt5.QtCore import Qt, QTimer, pyqtSignal, QThread
from PyQt5.QtGui import QFont
# 전역 변수로 미리 로딩된 라이브러리들을 저장
_preloaded_libs = {}
def preload_heavy_libraries(progress_callback=None):
"""무거운 라이브러리들을 메인 스레드에서 미리 로딩"""
global _preloaded_libs
optional_libs = [("scipy", "고급 수학 연산"), ("onnxruntime", "AI 모델 실행"), ("rembg", "배경 제거")]
available_libs = []
for lib_name, description in optional_libs:
if progress_callback:
progress_callback(f"🔍 {description} 라이브러리 미리 로딩 중...")
try:
if lib_name == "onnxruntime":
import onnxruntime
_preloaded_libs[lib_name] = onnxruntime
providers = onnxruntime.get_available_providers()
if progress_callback:
progress_callback(f"✅ {description} 라이브러리 미리 로딩 완료 (Providers: {len(providers)}개)")
available_libs.append(f"{lib_name} ({description})")
elif lib_name == "scipy":
import scipy
_preloaded_libs[lib_name] = scipy
if progress_callback:
progress_callback(f"✅ {description} 라이브러리 미리 로딩 완료")
available_libs.append(f"{lib_name} ({description})")
elif lib_name == "rembg":
import rembg
_preloaded_libs[lib_name] = rembg
if progress_callback:
progress_callback(f"✅ {description} 라이브러리 미리 로딩 완료")
available_libs.append(f"{lib_name} ({description})")
time.sleep(0.3)
except Exception as e:
if progress_callback:
progress_callback(f"⚠️ {description} 라이브러리 로딩 실패: {str(e)[:30]}...")
time.sleep(0.3)
return available_libs
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
class SafeModelLoaderThread(QThread):
"""안전한 모델 로딩 스레드 (이미 로딩된 라이브러리 확인)"""
finished = pyqtSignal(bool, str)
progress_update = pyqtSignal(str)
def run(self):
"""안전한 모델 로딩 프로세스"""
try:
self.progress_update.emit("🔄 Python 환경 확인 중...")
time.sleep(0.5)
# 1. 기본 라이브러리 확인
self.progress_update.emit("📦 기본 라이브러리 확인 중...")
try:
import math
import os
import sys
self.progress_update.emit("✅ 기본 라이브러리 확인 완료")
time.sleep(0.5)
except Exception as e:
self.progress_update.emit(f"❌ 기본 라이브러리 확인 실패: {e}")
self.finished.emit(False, f"기본 라이브러리 확인 실패: {e}")
return
# 2. 이미지 처리 라이브러리 확인
self.progress_update.emit("📸 이미지 처리 라이브러리 확인 중...")
try:
from PIL import Image
import numpy as np
self.progress_update.emit("✅ 이미지 처리 라이브러리 확인 완료")
time.sleep(0.5)
except Exception as e:
self.progress_update.emit(f"❌ 이미지 처리 라이브러리 확인 실패: {e}")
self.finished.emit(False, f"이미지 처리 라이브러리 확인 실패: {e}")
return
# 3. PyQt5 확인
self.progress_update.emit("🖥️ GUI 라이브러리 확인 중...")
try:
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QColor
self.progress_update.emit("✅ GUI 라이브러리 확인 완료")
time.sleep(0.5)
except Exception as e:
self.progress_update.emit(f"❌ GUI 라이브러리 확인 실패: {e}")
self.finished.emit(False, f"GUI 라이브러리 확인 실패: {e}")
return
# 4. 미리 로딩된 라이브러리들 확인
self.progress_update.emit("🔍 미리 로딩된 라이브러리들 확인 중...")
time.sleep(0.5)
available_libs = []
for lib_name, lib_module in _preloaded_libs.items():
if lib_name == "onnxruntime":
providers = lib_module.get_available_providers()
self.progress_update.emit(f"✅ AI 모델 실행 라이브러리 사용 가능 (Providers: {len(providers)}개)")
available_libs.append(f"{lib_name} (AI 모델 실행)")
elif lib_name == "scipy":
self.progress_update.emit(f"✅ 고급 수학 연산 라이브러리 사용 가능")
available_libs.append(f"{lib_name} (고급 수학 연산)")
elif lib_name == "rembg":
self.progress_update.emit(f"✅ 배경 제거 라이브러리 사용 가능")
available_libs.append(f"{lib_name} (배경 제거)")
time.sleep(0.3)
# 5. 최종 확인
self.progress_update.emit("🔍 최종 상태 확인 중...")
time.sleep(0.5)
# 성공 메시지 생성
if available_libs:
success_msg = f"앱 준비 완료! 사용 가능한 선택적 기능: {len(available_libs)}개"
else:
success_msg = "앱 준비 완료! (기본 기능만 사용 가능)"
self.progress_update.emit("🎉 초기화 완료!")
time.sleep(0.5)
self.finished.emit(True, success_msg)
except Exception as e:
self.progress_update.emit(f"💥 예상치 못한 오류: {str(e)}")
self.finished.emit(False, f"초기화 중 오류 발생: {str(e)}")
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
class SafeLoadingScreen(QWidget):
"""안전한 로딩 화면"""
loading_finished = pyqtSignal(bool, str)
def __init__(self):
super().__init__()
self.setupUI()
self.preload_then_start()
def setupUI(self):
"""UI 설정"""
self.setWindowTitle("안전한 로딩 테스트")
self.setFixedSize(400, 200)
layout = QVBoxLayout()
# 제목
title = QLabel("안전한 로딩 테스트")
title.setAlignment(Qt.AlignCenter)
title.setStyleSheet("font-size: 16px; font-weight: bold; margin: 10px;")
layout.addWidget(title)
# 상태 메시지
self.status_label = QLabel("초기화 중...")
self.status_label.setAlignment(Qt.AlignCenter)
self.status_label.setStyleSheet("padding: 10px; background-color: #f0f0f0; border-radius: 5px;")
layout.addWidget(self.status_label)
# 진행률 바
self.progress_bar = QProgressBar()
self.progress_bar.setRange(0, 0) # 무한 진행률
layout.addWidget(self.progress_bar)
self.setLayout(layout)
def preload_then_start(self):
"""메인 스레드에서 무거운 라이브러리 미리 로딩 후 QThread 시작"""
# 메인 스레드에서 무거운 라이브러리들을 미리 로딩
self.update_status("🚀 무거운 라이브러리들 미리 로딩 중...")
def progress_callback(message):
self.update_status(message)
QApplication.processEvents() # UI 업데이트 강제 실행
available_libs = preload_heavy_libraries(progress_callback)
self.update_status(f"✅ 무거운 라이브러리 미리 로딩 완료! ({len(available_libs)}개)")
time.sleep(1)
# 이제 QThread 시작
self.start_loading()
def start_loading(self):
"""로딩 시작"""
self.loader_thread = SafeModelLoaderThread()
self.loader_thread.finished.connect(self.on_loading_finished)
self.loader_thread.progress_update.connect(self.update_status)
self.loader_thread.start()
def update_status(self, message):
"""상태 업데이트"""
self.status_label.setText(message)
print(message) # 콘솔에도 출력
def on_loading_finished(self, success, message):
"""로딩 완료"""
self.progress_bar.setRange(0, 1)
self.progress_bar.setValue(1)
if success:
self.status_label.setText("✅ " + message)
self.status_label.setStyleSheet("padding: 10px; background-color: #d4edda; border-radius: 5px; color: #155724;")
else:
self.status_label.setText("❌ " + message)
self.status_label.setStyleSheet("padding: 10px; background-color: #f8d7da; border-radius: 5px; color: #721c24;")
print(f"로딩 결과: {'성공' if success else '실패'}")
print(f"메시지: {message}")
# 3초 후 종료
QTimer.singleShot(3000, self.close_app)
def close_app(self):
"""앱 종료"""
self.loading_finished.emit(True, "테스트 완료")
self.close()
def test_safe_loading():
"""안전한 로딩 테스트"""
app = QApplication(sys.argv)
loading = SafeLoadingScreen()
loading.show()
def on_finished(success, message):
print("테스트 완료!")
app.quit()
loading.loading_finished.connect(on_finished)
sys.exit(app.exec_())
if __name__ == "__main__":
test_safe_loading()
|
성공하는 예시 성공하는 cli 프로그램
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
| #!/usr/bin/env python3
"""
안전한 로딩 테스트 (CLI 전용)
"""
import time
import importlib
def check_basic_libraries():
print("🔄 Python 환경 확인 중...")
time.sleep(0.3)
print("📦 기본 라이브러리 확인 중...")
try:
import math
import os
import sys
print("✅ 기본 라이브러리 확인 완료")
return True
except Exception as e:
print(f"❌ 기본 라이브러리 확인 실패: {e}")
return False
def check_image_libraries():
print("📸 이미지 처리 라이브러리 확인 중...")
try:
from PIL import Image
import numpy as np
print("✅ 이미지 처리 라이브러리 확인 완료")
return True
except Exception as e:
print(f"❌ 이미지 처리 라이브러리 확인 실패: {e}")
return False
def check_gui_libraries():
print("🖥️ GUI 라이브러리 확인 중...")
try:
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QColor
print("✅ GUI 라이브러리 확인 완료")
return True
except Exception as e:
print(f"❌ GUI 라이브러리 확인 실패: {e}")
return False
def check_optional_libraries():
print("🔍 선택적 라이브러리 확인 중...")
optional_libs = [("scipy", "고급 수학 연산"), ("onnxruntime", "AI 모델 실행"), ("rembg", "배경 제거")]
available = []
for lib_name, description in optional_libs:
print(f"🔍 {description} 라이브러리 확인 중...")
try:
if lib_name == "onnxruntime":
import onnxruntime
providers = onnxruntime.get_available_providers()
print(f"✅ {description} 라이브러리 사용 가능 (Providers: {len(providers)}개)")
elif lib_name == "scipy":
import scipy
print(f"✅ {description} 라이브러리 사용 가능")
elif lib_name == "rembg":
import rembg
print(f"✅ {description} 라이브러리 사용 가능")
available.append(description)
except Exception as e:
print(f"⚠️ {description} 라이브러리 오류: {str(e)[:60]}...")
time.sleep(0.2)
return available
def main():
print("🚀 안전한 CLI 로딩 테스트 시작\n")
time.sleep(0.3)
available = check_optional_libraries() ## 중요. 무거운거 먼저 로딩해야함.
ok1 = check_basic_libraries()
ok2 = check_image_libraries()
ok3 = check_gui_libraries()
print("\n🔍 최종 상태 확인 중...")
time.sleep(0.3)
if ok1 and ok2 and ok3:
print("🎉 초기화 완료!")
if available:
print(f"✅ 앱 준비 완료! 사용 가능한 선택적 기능: {len(available)}개")
else:
print("⚠️ 앱 준비 완료 (선택 기능 없음)")
else:
print("❌ 초기화 실패: 필수 라이브러리 중 일부가 누락되었습니다.")
print("🧪 테스트 완료!")
if __name__ == "__main__":
main()
|
성공하는 gui프로그램
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
| #!/usr/bin/env python3
"""
GUI 환경에서 DLL 로딩 문제 해결 테스트
CLI 성공 방식을 GUI에 적용
"""
import sys
import os
import time
import threading
# 🔥 핵심: PyQt5 import 전에 무거운 라이브러리들을 먼저 로딩
print("🚀 GUI 환경 DLL 로딩 문제 해결 테스트")
print("💡 핵심: PyQt5 시작 전에 무거운 라이브러리 미리 로딩")
print()
def preload_heavy_libraries():
"""PyQt5 시작 전에 무거운 라이브러리들 미리 로딩"""
print("🔄 PyQt5 시작 전 무거운 라이브러리 미리 로딩...")
# 환경 변수 설정 (DLL 로딩 도움)
if hasattr(os, "add_dll_directory"):
# Python 3.8+ Windows에서 DLL 경로 추가
python_dir = os.path.dirname(sys.executable)
if os.path.exists(python_dir):
os.add_dll_directory(python_dir)
print(f" 📁 DLL 경로 추가: {python_dir}")
preloaded = []
# 1. scipy 먼저 (가장 안전)
print("🔍 scipy 미리 로딩 중...")
try:
import scipy
preloaded.append("scipy")
print(" ✅ scipy 미리 로딩 성공")
except Exception as e:
print(f" ⚠️ scipy 미리 로딩 실패: {str(e)[:50]}...")
# 2. onnxruntime 시도
print("🔍 onnxruntime 미리 로딩 중...")
try:
import onnxruntime
providers = onnxruntime.get_available_providers()
preloaded.append("onnxruntime")
print(f" ✅ onnxruntime 미리 로딩 성공 (Providers: {len(providers)}개)")
except Exception as e:
print(f" ⚠️ onnxruntime 미리 로딩 실패: {str(e)[:50]}...")
# 3. rembg 시도
print("🔍 rembg 미리 로딩 중...")
try:
import rembg
preloaded.append("rembg")
print(" ✅ rembg 미리 로딩 성공")
except Exception as e:
print(f" ⚠️ rembg 미리 로딩 실패: {str(e)[:50]}...")
print(f"✅ 미리 로딩 완료: {len(preloaded)}개 라이브러리")
print()
return preloaded
# 핵심: PyQt5 import 전에 무거운 라이브러리들 미리 로딩
preloaded_libs = preload_heavy_libraries()
# 이제 PyQt5 import (무거운 라이브러리들이 이미 로딩됨)
print("🖥️ PyQt5 import 중...")
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel, QProgressBar
from PyQt5.QtCore import Qt, QTimer, pyqtSignal, QObject
from PyQt5.QtGui import QFont
print("✅ PyQt5 import 성공")
print()
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
class ThreadSafeSignals(QObject):
"""스레드 안전한 시그널 클래스"""
finished = pyqtSignal(bool, str)
progress_update = pyqtSignal(str)
class FixedModelLoaderThread:
"""수정된 모델 로딩 스레드"""
def __init__(self, signals, preloaded_libs):
self.signals = signals
self.preloaded_libs = preloaded_libs
self.thread = None
def start(self):
"""스레드 시작"""
self.thread = threading.Thread(target=self.run)
self.thread.daemon = True
self.thread.start()
def run(self):
"""수정된 모델 로딩 프로세스"""
try:
self.signals.progress_update.emit("🔄 Python 환경 확인 중...")
time.sleep(0.3)
# 1. 기본 라이브러리 확인
self.signals.progress_update.emit("📦 기본 라이브러리 확인 중...")
try:
import math
import os
import sys
self.signals.progress_update.emit("✅ 기본 라이브러리 확인 완료")
time.sleep(0.3)
except Exception as e:
self.signals.progress_update.emit(f"❌ 기본 라이브러리 확인 실패: {e}")
self.signals.finished.emit(False, f"기본 라이브러리 확인 실패: {e}")
return
# 2. 이미지 처리 라이브러리 확인
self.signals.progress_update.emit("📸 이미지 처리 라이브러리 확인 중...")
try:
from PIL import Image
import numpy as np
self.signals.progress_update.emit("✅ 이미지 처리 라이브러리 확인 완료")
time.sleep(0.3)
except Exception as e:
self.signals.progress_update.emit(f"❌ 이미지 처리 라이브러리 확인 실패: {e}")
self.signals.finished.emit(False, f"이미지 처리 라이브러리 확인 실패: {e}")
return
# 3. GUI 라이브러리 확인 (이미 로딩됨)
self.signals.progress_update.emit("🖥️ GUI 라이브러리 확인 중...")
self.signals.progress_update.emit("✅ GUI 라이브러리 확인 완료")
time.sleep(0.3)
# 4. 미리 로딩된 라이브러리들 확인
self.signals.progress_update.emit("🔍 미리 로딩된 라이브러리들 확인 중...")
available_count = 0
for lib in ["scipy", "onnxruntime", "rembg"]:
if lib in self.preloaded_libs:
if lib == "onnxruntime":
try:
import onnxruntime
providers = onnxruntime.get_available_providers()
self.signals.progress_update.emit(f"✅ {lib} 사용 가능 (Providers: {len(providers)}개)")
except:
self.signals.progress_update.emit(f"⚠️ {lib} 재확인 실패")
continue
else:
self.signals.progress_update.emit(f"✅ {lib} 사용 가능")
available_count += 1
time.sleep(0.2)
# 5. 최종 확인
self.signals.progress_update.emit("🔍 최종 상태 확인 중...")
time.sleep(0.3)
success_msg = f"앱 준비 완료! 사용 가능한 선택적 기능: {available_count}개"
self.signals.progress_update.emit("🎉 초기화 완료!")
time.sleep(0.3)
self.signals.finished.emit(True, success_msg)
except Exception as e:
self.signals.progress_update.emit(f"💥 예상치 못한 오류: {str(e)}")
self.signals.finished.emit(False, f"초기화 중 오류 발생: {str(e)}")
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
class FixedLoadingScreen(QWidget):
"""수정된 로딩 화면"""
loading_finished = pyqtSignal(bool, str)
def __init__(self, preloaded_libs):
super().__init__()
self.preloaded_libs = preloaded_libs
self.setupUI()
self.start_loading()
def setupUI(self):
"""UI 설정"""
self.setWindowTitle("GUI 환경 DLL 로딩 문제 해결 테스트")
self.setFixedSize(450, 250)
layout = QVBoxLayout()
# 제목
title = QLabel("GUI 환경 DLL 로딩 문제 해결 테스트")
title.setAlignment(Qt.AlignCenter)
title.setStyleSheet("font-size: 16px; font-weight: bold; margin: 10px;")
layout.addWidget(title)
# 미리 로딩 정보
preload_info = QLabel(f"미리 로딩된 라이브러리: {len(self.preloaded_libs)}개")
preload_info.setAlignment(Qt.AlignCenter)
preload_info.setStyleSheet("font-size: 12px; color: #666; margin: 5px;")
layout.addWidget(preload_info)
# 상태 메시지
self.status_label = QLabel("초기화 중...")
self.status_label.setAlignment(Qt.AlignCenter)
self.status_label.setStyleSheet("padding: 10px; background-color: #f0f0f0; border-radius: 5px;")
layout.addWidget(self.status_label)
# 진행률 바
self.progress_bar = QProgressBar()
self.progress_bar.setRange(0, 0) # 무한 진행률
layout.addWidget(self.progress_bar)
self.setLayout(layout)
def start_loading(self):
"""로딩 시작"""
self.signals = ThreadSafeSignals()
self.signals.finished.connect(self.on_loading_finished)
self.signals.progress_update.connect(self.update_status)
self.loader_thread = FixedModelLoaderThread(self.signals, self.preloaded_libs)
self.loader_thread.start()
def update_status(self, message):
"""상태 업데이트"""
self.status_label.setText(message)
print(message)
def on_loading_finished(self, success, message):
"""로딩 완료"""
self.progress_bar.setRange(0, 1)
self.progress_bar.setValue(1)
if success:
self.status_label.setText("✅ " + message)
self.status_label.setStyleSheet("padding: 10px; background-color: #d4edda; border-radius: 5px; color: #155724;")
else:
self.status_label.setText("❌ " + message)
self.status_label.setStyleSheet("padding: 10px; background-color: #f8d7da; border-radius: 5px; color: #721c24;")
print(f"로딩 결과: {'성공' if success else '실패'}")
print(f"메시지: {message}")
print(f"미리 로딩된 라이브러리: {', '.join(self.preloaded_libs)}")
# 3초 후 종료
QTimer.singleShot(3000, self.close_app)
def close_app(self):
"""앱 종료"""
self.loading_finished.emit(True, "테스트 완료")
self.close()
def test_fixed_loading():
"""수정된 로딩 테스트"""
app = QApplication(sys.argv)
loading = FixedLoadingScreen(preloaded_libs)
loading.show()
def on_finished(success, message):
print("테스트 완료!")
app.quit()
loading.loading_finished.connect(on_finished)
sys.exit(app.exec_())
if __name__ == "__main__":
test_fixed_loading()
|
#Windows, #PyQt5, #ONNX_RUNTIME, #DLL, #python, #gui, #ai, #라이브러리_로딩, #의존성_관리