openAI를 활용하는 실습을 진행하며,
이를 묶어서 하나의 작업물로 업뎃하며 실습을 하려고 한다.
현재 실습에사 QyQT5을 이용하여 앱 구성을 진행하고 있는데,
프론트엔드 부분은 간략하게 구현하고 싶어 Qtdesinger 앱을 이용하기러 하였다.
mac에선 터미널 명령어를 통한 다운이 되지 않아, 공식홈에서 다운함

앱을 이용하면 꽤 직관적으로 프론트를 만들어 낼 수 있다.
좌측 리스트에서 원하는 레이아웃을 드래그&드롭하는 형식이고,
우측 객체 탐색기에서 객체별 이름을 바꿔줄 수 있다.
버튼은 기능_btn, 입력창은 기능_input
이런식으로 이름을 바꿔주면 코드 입력할때 편리하다.

이렇게 구성한 파일을 저장하면 QT.ui파일로 저장되는데
pyuic5 -x main_window.ui -o main_window_ui.py
터미널에서 해당 폴더로 들어가,명령시 파이썬 파일로 바뀐다.
from main_window_ui import Ui_MainWindow
로 임포트하여 사용할 수 있는 상태가 준비된다!
앞선 번역기 실습에서 Qthread를 사용했지만,없어도 동작했음.
그러나 image는 Qthread없인 지연시간으로 앱이 자동 종료됌

lass ImageWorker(QObject):
finished = pyqtSignal(str)
error = pyqtSignal(str)
def __init__(self, client, prompt):
super().__init__()
self.client = client
self.prompt = prompt
def run(self):
try:
response = self.client.images.generate(
model="dall-e-3",
prompt=self.prompt,
n=1,
size="1024x1024",
response_format="url"
)
image_url = response.data[0].url
self.finished.emit(image_url)
except Exception as e:
traceback.print_exc()
self.error.emit(str(e))
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.client = OpenAI(api_key=os.getenv("API_KEY"))
# 메뉴 전환
self.ui.menu_list.currentRowChanged.connect(self.ui.stackedWidget.setCurrentIndex)
# 버튼 이벤트
self.ui.poem_generate_btn.clicked.connect(self.generate_poem)
self.ui.translate_btn.clicked.connect(self.translate_text)
self.ui.image_generate_btn.clicked.connect(self.generate_image)
self.ui.audio_note_btn.clicked.connect(self.generate_audio_note)
self.show()
def generate_image(self):
prompt = self.ui.image_prompt_input.text()
if not prompt:
self.ui.image_display_label.setText("이미지 프롬프트를 입력해주세요.")
return
self.ui.image_generate_btn.setEnabled(False)
self.ui.image_display_label.setText("이미지 생성 중입니다...")
self.image_thread = QThread()
self.image_worker = ImageWorker(self.client, prompt)
self.image_worker.moveToThread(self.image_thread)
self.image_thread.started.connect(self.image_worker.run)
self.image_worker.finished.connect(self.handle_image_result)
self.image_worker.error.connect(self.handle_image_error)
self.image_worker.finished.connect(self.image_thread.quit)
self.image_worker.finished.connect(self.image_worker.deleteLater)
self.image_thread.finished.connect(self.image_thread.deleteLater)
self.image_thread.start()
def handle_image_result(self, image_url):
try:
img_data = requests.get(image_url).content
pixmap = QPixmap()
pixmap.loadFromData(img_data)
self.ui.image_display_label.setPixmap(pixmap)
except Exception as e:
self.ui.image_display_label.setText(f"이미지를 불러오는데 실패했습니다: {e}")
finally:
self.ui.image_generate_btn.setEnabled(True)
def handle_image_error(self, error_msg):
self.ui.image_display_label.setText(f"오류가 발생했습니다: {error_msg}")
self.ui.image_generate_btn.setEnabled(True)
생성된 이미지 url을 뽑는 것이 아니라, 화면에 보여주기 위해
QPixmap()를 활용하였다.
url은 데이터스트림으로 requset로 바이터 데이터를 저장한다
이후 Qpixmap.loadFormData(bytes)로 객체를 생성하고,
Qlable을 통해 객체를 화면에 띄운다.