ㅁ 개요
O 프로젝트 소개
- 이번 글은 이전글(
2024.07.07 - [파이썬 프로젝트 강좌(초급)/환율 계산기] - 환율 계산기 만들기 - 5. GUI 환율 계산기 - 실행버튼 없이 실행(엔터시 실행))에 이은 7번째 마지막 글로 구글에서 "환율"로 검색 시 환율 계산 화면이 나오는데, 이와 가장 유사하게 만들어 보는 방법에 대해 알아보겠습니다.
O 완성된 프로그램 실행 화면
1. 6_1.py 실행 시 아래와 같이 잘 실행됩니다.
하지만 대상통화의 KRW->EUR로 변경시 EUR 1373.99의 값에 해당하는 USD의 값이 변경되지 않고, 실행결과 창에 "하나의 입력 필드에 값을 입력해 주세요."라고 뜹니다. 이부분을 수정해야 합니다.
2. 6_2.py 실행 시 아래와 같이 잘 실행됩니다.
하지만 대상통화의 KRW->EUR로 변경시 EUR 1373.99의 값에 해당하는 USD의 값이 변경되지 않고 EUR 옆의 lineEdit_2의 값이 변경되었습니다. 이부분을 수정해야 합니다.
3. 6_3.py 실행 시 아래와 같이 잘 실행됩니다.
대상통화의 KRW->EUR로 변경시 EUR 1373.99의 값에 해당하는 USD의 값이 1497.64로 우리가 예상한 대로 잘 변경되었습니다.
ㅁ 세부 내용
O 완성된 소스
소스파일 : 6_1.py
# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic, QtWidgets
import os
from PyQt5.QtGui import *
import re
import requests
import json
from datetime import datetime
form_class = uic.loadUiType("exchangeRate1.ui")[0]
# lineEdit 변경시 -> lineEdit_2에 값 자동 삽입
# lineEdit_2 변경시 -> lineEdit에 값 자동 삽입하도록 수정
class MyWindow(QMainWindow, form_class):
def __init__(self):
super().__init__()
self.setFixedSize(800,600)
self.setWindowIcon(QIcon("pagichacha.png"))
self.setupUi(self)
self.is_updating = False
self.comboBox.currentIndexChanged.connect(self.calculate)
self.comboBox_2.currentIndexChanged.connect(self.calculate)
self.lineEdit.textChanged.connect(self.calculate_from_lineEdit)
self.lineEdit_2.textChanged.connect(self.calculate_from_lineEdit2)
def calculate_from_lineEdit(self):
if not self.is_updating:
self.is_updating = True
self.calculate(source='lineEdit')
self.is_updating = False
def calculate_from_lineEdit2(self):
if not self.is_updating:
self.is_updating = True
self.calculate(source='lineEdit2')
self.is_updating = False
def calculate(self, source=None):
fromCurrency = self.comboBox.currentText()
toCurrency = self.comboBox_2.currentText()
if source == 'lineEdit' or (source is None and self.lineEdit.text()):
self.convert_currency(self.lineEdit, self.lineEdit_2, fromCurrency, toCurrency)
elif source == 'lineEdit2' or (source is None and self.lineEdit_2.text()):
self.convert_currency(self.lineEdit_2, self.lineEdit, toCurrency, fromCurrency)
else:
self.textEdit.setText("하나의 입력 필드에 값을 입력해 주세요.")
def convert_currency(self, input_field, output_field, from_currency, to_currency):
present_value = input_field.text()
if re.match(r'^-?\d+(?:\.\d+)?$', present_value):
present_value = float(present_value)
rate, last_updated = self.get_exchange_rate(from_currency, to_currency)
converted_value = present_value * rate
output_field.setText(f"{converted_value:.6f}")
self.update_result_text(present_value, converted_value, rate, from_currency, to_currency, last_updated)
else:
if present_value: # 입력값이 있을 때만 메시지 표시
self.textEdit.setText("입력값은 숫자가 아닙니다. 숫자를 입력하여 주시기 바랍니다.")
else:
output_field.clear() # 입력값이 없으면 출력 필드도 클리어
self.textEdit.clear() # 결과 텍스트도 클리어
def update_result_text(self, input_value, output_value, rate, from_currency, to_currency, last_updated):
result_text = f"{input_value:,.6f} {from_currency}는 {output_value:,.6f} {to_currency} 입니다."
result_text += f"\n\n환율: 1 {from_currency} = {rate:,.6f} {to_currency}"
result_text += f"\n마지막 업데이트: {last_updated}"
self.textEdit.setText(result_text)
def get_exchange_rate(self, base_currency, target_currency):
url = f"https://api.exchangerate-api.com/v4/latest/{base_currency}"
try:
response = requests.get(url)
data = json.loads(response.text)
if response.status_code == 200:
rate = data['rates'][target_currency]
last_updated = datetime.fromtimestamp(data['time_last_updated'])
print(f"현재 환율: 1 {base_currency} = {rate} {target_currency}")
print(f"마지막 업데이트: {last_updated}")
return rate, last_updated
else:
print("환율 정보를 가져오는데 실패했습니다.")
except requests.exceptions.RequestException as e:
print(f"오류 발생: {e}")
app=QApplication(sys.argv)
window = MyWindow()
window.show()
print("Before event loop")
app.exec_()
print("After event loop")
소스파일 : 6_2.py
# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic, QtWidgets
import os
from PyQt5.QtGui import *
import re
import requests
import json
from datetime import datetime
form_class = uic.loadUiType("exchangeRate1.ui")[0]
# lineEdit 변경시 -> lineEdit_2에 값 자동 삽입
# lineEdit_2 변경시 -> lineEdit에 값 자동 삽입하도록 수정
class MyWindow(QMainWindow, form_class):
def __init__(self):
super().__init__()
self.setFixedSize(800,600)
self.setWindowIcon(QIcon("pagichacha.png"))
self.setupUi(self)
self.is_updating = False
self.comboBox.currentIndexChanged.connect(self.on_combo_changed)
self.comboBox_2.currentIndexChanged.connect(self.on_combo_changed)
self.lineEdit.textChanged.connect(self.calculate_from_lineEdit)
self.lineEdit_2.textChanged.connect(self.calculate_from_lineEdit2)
def on_combo_changed(self):
if self.lineEdit.text():
self.calculate_from_lineEdit()
elif self.lineEdit_2.text():
self.calculate_from_lineEdit2()
def calculate_from_lineEdit(self):
if not self.is_updating:
self.is_updating = True
self.calculate(source='lineEdit')
self.is_updating = False
def calculate_from_lineEdit2(self):
if not self.is_updating:
self.is_updating = True
self.calculate(source='lineEdit2')
self.is_updating = False
def calculate(self, source=None):
fromCurrency = self.comboBox.currentText()
toCurrency = self.comboBox_2.currentText()
if source == 'lineEdit' or (source is None and self.lineEdit.text()):
self.convert_currency(self.lineEdit, self.lineEdit_2, fromCurrency, toCurrency)
elif source == 'lineEdit2' or (source is None and self.lineEdit_2.text()):
self.convert_currency(self.lineEdit_2, self.lineEdit, toCurrency, fromCurrency)
def convert_currency(self, input_field, output_field, from_currency, to_currency):
present_value = input_field.text()
if re.match(r'^-?\d+(?:\.\d+)?$', present_value):
present_value = float(present_value)
rate, last_updated = self.get_exchange_rate(from_currency, to_currency)
converted_value = present_value * rate
output_field.setText(f"{converted_value:.6f}")
self.update_result_text(present_value, converted_value, rate, from_currency, to_currency, last_updated)
else:
if present_value: # 입력값이 있을 때만 메시지 표시
self.textEdit.setText("입력값은 숫자가 아닙니다. 숫자를 입력하여 주시기 바랍니다.")
else:
output_field.clear() # 입력값이 없으면 출력 필드도 클리어
self.textEdit.clear() # 결과 텍스트도 클리어
def update_result_text(self, input_value, output_value, rate, from_currency, to_currency, last_updated):
result_text = f"{input_value:,.6f} {from_currency}는 {output_value:,.6f} {to_currency} 입니다."
result_text += f"\n\n환율: 1 {from_currency} = {rate:,.6f} {to_currency}"
result_text += f"\n마지막 업데이트: {last_updated}"
self.textEdit.setText(result_text)
def get_exchange_rate(self, base_currency, target_currency):
url = f"https://api.exchangerate-api.com/v4/latest/{base_currency}"
try:
response = requests.get(url)
data = json.loads(response.text)
if response.status_code == 200:
rate = data['rates'][target_currency]
last_updated = datetime.fromtimestamp(data['time_last_updated'])
print(f"현재 환율: 1 {base_currency} = {rate} {target_currency}")
print(f"마지막 업데이트: {last_updated}")
return rate, last_updated
else:
print("환율 정보를 가져오는데 실패했습니다.")
except requests.exceptions.RequestException as e:
print(f"오류 발생: {e}")
app=QApplication(sys.argv)
window = MyWindow()
window.show()
print("Before event loop")
app.exec_()
print("After event loop")
소스파일 : 6_3.py
# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic, QtWidgets
import os
from PyQt5.QtGui import *
import re
import requests
import json
from datetime import datetime
form_class = uic.loadUiType("exchangeRate1.ui")[0]
# lineEdit 변경시 -> lineEdit_2에 값 자동 삽입
# lineEdit_2 변경시 -> lineEdit에 값 자동 삽입하도록 수정
class MyWindow(QMainWindow, form_class):
def __init__(self):
super().__init__()
self.setFixedSize(800,600)
self.setWindowIcon(QIcon("pagichacha.png"))
self.setupUi(self)
self.is_updating = False
self.comboBox.currentIndexChanged.connect(self.on_combo1_changed)
self.comboBox_2.currentIndexChanged.connect(self.on_combo2_changed)
self.lineEdit.textChanged.connect(self.calculate_from_lineEdit)
self.lineEdit_2.textChanged.connect(self.calculate_from_lineEdit2)
def on_combo1_changed(self):
if self.lineEdit.text():
self.calculate_from_lineEdit()
def on_combo2_changed(self):
if self.lineEdit_2.text():
self.calculate_from_lineEdit2()
def calculate_from_lineEdit(self):
if not self.is_updating:
self.is_updating = True
self.calculate(source='lineEdit')
self.is_updating = False
def calculate_from_lineEdit2(self):
if not self.is_updating:
self.is_updating = True
self.calculate(source='lineEdit2')
self.is_updating = False
def calculate(self, source=None):
fromCurrency = self.comboBox.currentText()
toCurrency = self.comboBox_2.currentText()
if source == 'lineEdit' or (source is None and self.lineEdit.text()):
self.convert_currency(self.lineEdit, self.lineEdit_2, fromCurrency, toCurrency)
elif source == 'lineEdit2' or (source is None and self.lineEdit_2.text()):
self.convert_currency(self.lineEdit_2, self.lineEdit, toCurrency, fromCurrency)
def convert_currency(self, input_field, output_field, from_currency, to_currency):
present_value = input_field.text()
if re.match(r'^-?\d+(?:\.\d+)?$', present_value):
present_value = float(present_value)
rate, last_updated = self.get_exchange_rate(from_currency, to_currency)
converted_value = present_value * rate
output_field.setText(f"{converted_value:.6f}")
self.update_result_text(present_value, converted_value, rate, from_currency, to_currency, last_updated)
else:
if present_value: # 입력값이 있을 때만 메시지 표시
self.textEdit.setText("입력값은 숫자가 아닙니다. 숫자를 입력하여 주시기 바랍니다.")
else:
output_field.clear() # 입력값이 없으면 출력 필드도 클리어
self.textEdit.clear() # 결과 텍스트도 클리어
def update_result_text(self, input_value, output_value, rate, from_currency, to_currency, last_updated):
result_text = f"{input_value:,.6f} {from_currency}는 {output_value:,.6f} {to_currency} 입니다."
result_text += f"\n\n환율: 1 {from_currency} = {rate:,.6f} {to_currency}"
result_text += f"\n마지막 업데이트: {last_updated}"
self.textEdit.setText(result_text)
def get_exchange_rate(self, base_currency, target_currency):
url = f"https://api.exchangerate-api.com/v4/latest/{base_currency}"
try:
response = requests.get(url)
data = json.loads(response.text)
if response.status_code == 200:
rate = data['rates'][target_currency]
last_updated = datetime.fromtimestamp(data['time_last_updated'])
print(f"현재 환율: 1 {base_currency} = {rate} {target_currency}")
print(f"마지막 업데이트: {last_updated}")
return rate, last_updated
else:
print("환율 정보를 가져오는데 실패했습니다.")
except requests.exceptions.RequestException as e:
print(f"오류 발생: {e}")
app=QApplication(sys.argv)
window = MyWindow()
window.show()
print("Before event loop")
app.exec_()
print("After event loop")
O 소스 실행 방법
O 주요 내용
아래 소스코드에 대한 주요 내용만 설명하겠습니다.
소스 파일 : 6_1.py
라인에디트에 값 입력시 상대 통화의 라인에디트에 계산된 환율이 잘 입력되고 있으나, 콤보박스 변경시 별다른 코드를 지정해주지 않아 "하나의 입력 필드에 값을 입력해 주세요" 라고만 뜹니다.
소스코드는 아래 화면을 참고하여 주시기 바랍니다.
소스 파일 : 6_2.py
comboBox_2변경시 lineEdit에 값이 들어가지 않고, lineEdit_2에 값이 입력되고 있습니다.
해당 이유는 아래 설명을 참고하여 주시기 바랍니다.
소스 파일 : 6_3.py
콤보박스 이벤트별로 on_combo1,2_changed() 메소드로 분리하여 각 각 다른 ~lineEdit()/~lineEdit2() 메소드를 호출하도록 하여 상대편 라인에디트에 값이 입력될 수 있도록 개선하였습니다.
ㅁ 정리
O 우리가 배운 내용
여기까지 읽어 주셔서 감사드리며, 위의 내용이 유익하셨다면, 광고 한번씩만 클릭 부탁드립니다.
감사합니다.
'파이썬 프로젝트 강좌(초급) > 환율 계산기' 카테고리의 다른 글
환율 계산기 만들기 - 5. GUI 환율 계산기 - 실행버튼 없이 실행(엔터시 실행) (0) | 2024.07.17 |
---|---|
환율 계산기 만들기 - 4. GUI 환율 계산기 - 실행버튼 없이 실행(change 이벤트) (0) | 2024.07.13 |
환율 계산기 만들기 - 3. GUI 환율 계산기 - 실행버튼 클릭(양방향) (0) | 2024.07.13 |
환율 계산기 만들기 - 2.GUI 환율 계산기 - 실행버튼 클릭(한방향) (1) | 2024.07.13 |
환율 계산기 만들기 - 1.텍스트 환율 계산기 (0) | 2024.07.13 |