ㅁ 개요
O 프로젝트 소개
- 이번 글은 이전글(
2024.07.07 - [파이썬 프로젝트 강좌(초급)/환율 계산기] - 환율 계산기 만들기 - 4. GUI 환율 계산기 - 실행버튼 없이 실행(change 이벤트))에 이은 6번째 글로 아래 2가지로 프로그램을 개선하는 방법에 대하여 알아 보겠습니다.
1. 실행버튼을 클릭하지 않고, change이벤트가 발생 시 실행하되, 여기서는 변경 발생 후 1초 후에 실행되도록 시간 딜레이를 주어 보겠습니다.
2.위의 경우 여러가지 문제점이 있으므로 시간 딜레이 대신 엔터 이벤트가 발생한 경우 실행되도록 수정해 보고, 눈에 띄도록 환율 계산 결과의 색상을 바꿔 보도록 하겠습니다.
O 완성된 프로그램 실행 화면
1. 5_1.py 실행 후 lineEdit에 1입력 시(change이벤트 발생) 1초 후에 lineEdit_2(대상통화 입력란)와 textEdit(실행결과)에 환율정보가 나타납니다.
2. 5_2.py 실행 후 lineEdit에 1입력 후 엔터를 치면 lineEdit_2(대상통화 입력란)와 textEdit(실행결과)에 환율정보가 나타납니다.
3. 5_3.py 실행 후 lineEdit에 1입력 후 엔터를 치면 lineEdit_2(대상통화 입력란)와 textEdit(실행결과)에 환율정보가 색상이 표시되어 나타납니다.
ㅁ 세부 내용
O 완성된 소스
소스파일 : 5_1.py
# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic, QtWidgets
from PyQt5.QtGui import *
from PyQt5.QtCore import QTimer
import os
import re
import requests
import json
from datetime import datetime
form_class = uic.loadUiType("exchangeRate2.ui")[0]
class MyWindow(QMainWindow, form_class):
def __init__(self):
super().__init__()
self.setFixedSize(800,600)
self.setWindowIcon(QIcon("pagichacha.png"))
self.setupUi(self)
###################################
# 타이머 초기화 (값입력 후 2초 후에 환율 표시)
###################################
self.timer = QTimer(self)
self.timer.setSingleShot(True)
self.timer.timeout.connect(self.calculate)
###################################
self.comboBox.currentIndexChanged.connect(self.start_timer) ####<---------------------
self.comboBox_2.currentIndexChanged.connect(self.start_timer)
self.lineEdit.textChanged.connect(self.start_timer)
self.lineEdit_2.textChanged.connect(self.start_timer)
########### 타이머 초기화 시작 #################
def start_timer(self):
self.timer.start(1000) # 500ms 후에 calculate 함수 호출
########### 타이머 초기화 끝 #################
def calculate(self):
fromCurrency = self.comboBox.currentText()
toCurrency = self.comboBox_2.currentText()
# lineEdit에 값이 있는 경우
if self.lineEdit.text() and not self.lineEdit_2.text():
self.convert_currency(self.lineEdit, self.lineEdit_2, fromCurrency, toCurrency)
# lineEdit_2에 값이 있는 경우
elif self.lineEdit_2.text() and not self.lineEdit.text():
self.convert_currency(self.lineEdit_2, self.lineEdit, toCurrency, fromCurrency)
# 둘 다 값이 있거나 둘 다 값이 없는 경우
else:
self.textEdit.setText("하나의 입력 필드에만 값을 입력해 주세요.")
self.timer.stop() # 타이머를 멈추지 않으면 2초 후 다시 실행됨
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:
self.textEdit.setText("입력값은 숫자가 아닙니다. 숫자를 입력하여 주시기 바랍니다.")
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")
소스파일 : 5_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("exchangeRate2.ui")[0]
class MyWindow(QMainWindow, form_class):
def __init__(self):
super().__init__()
self.setFixedSize(800,600)
self.setWindowIcon(QIcon("pagichacha.png"))
self.setupUi(self)
# self.is_clearing = False
# self.pushButton.clicked.connect(self.main)
# 이벤트 핸들러 연결
# self.pushButton.clicked.connect(self.calculate)
self.comboBox.currentIndexChanged.connect(self.clear_inputs)
self.comboBox_2.currentIndexChanged.connect(self.clear_inputs)
###### 값 입력 후 엔터를 치면 환율 변환 하기 ################
self.lineEdit.returnPressed.connect(self.calculate)
self.lineEdit_2.returnPressed.connect(self.calculate)
##########################################################
############# 라인에디터 및 텍스트 에디터의 내용 삭제 ############
def clear_inputs(self):
self.lineEdit.clear()
self.lineEdit_2.clear()
self.textEdit.clear()
def calculate(self):
# if self.is_clearing: # 초기화 중이면 함수 종료
# return
fromCurrency = self.comboBox.currentText()
toCurrency = self.comboBox_2.currentText()
# lineEdit에 값이 있는 경우
if self.lineEdit.text() and not self.lineEdit_2.text():
self.convert_currency(self.lineEdit, self.lineEdit_2, fromCurrency, toCurrency)
# lineEdit_2에 값이 있는 경우
elif self.lineEdit_2.text() and not self.lineEdit.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)
# 계산 후 입력 필드 초기화
# self.is_clearing = True # 초기화 시작
##### 텍스트 에디터에 뿌려주고 라인에디터는 클리어 ##############
self.lineEdit.clear()
self.lineEdit_2.clear()
# self.is_clearing = False # 초기화 종료
else:
self.textEdit.setText("입력값은 숫자가 아닙니다. 숫자를 입력하여 주시기 바랍니다.")
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")
소스파일 : 5_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("exchangeRate2.ui")[0]
class MyWindow(QMainWindow, form_class):
def __init__(self):
super().__init__()
self.setFixedSize(800,600)
self.setWindowIcon(QIcon("pagichacha.png"))
self.setupUi(self)
# self.is_clearing = False
# self.pushButton.clicked.connect(self.main)
# 이벤트 핸들러 연결
# self.pushButton.clicked.connect(self.calculate)
self.comboBox.currentIndexChanged.connect(self.clear_inputs)
self.comboBox_2.currentIndexChanged.connect(self.clear_inputs)
self.lineEdit.returnPressed.connect(self.calculate)
self.lineEdit_2.returnPressed.connect(self.calculate)
def clear_inputs(self):
self.lineEdit.clear()
self.lineEdit_2.clear()
self.textEdit.clear()
def calculate(self):
# if self.is_clearing: # 초기화 중이면 함수 종료
# return
fromCurrency = self.comboBox.currentText()
toCurrency = self.comboBox_2.currentText()
# lineEdit에 값이 있는 경우
if self.lineEdit.text() and not self.lineEdit_2.text():
self.convert_currency(self.lineEdit, self.lineEdit_2, fromCurrency, toCurrency)
# lineEdit_2에 값이 있는 경우
elif self.lineEdit_2.text() and not self.lineEdit.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)
# 계산 후 입력 필드 초기화
# self.is_clearing = True # 초기화 시작
self.lineEdit.clear()
self.lineEdit_2.clear()
# self.is_clearing = False # 초기화 종료
else:
self.textEdit.setText("입력값은 숫자가 아닙니다. 숫자를 입력하여 주시기 바랍니다.")
def update_result_text(self, input_value, output_value, rate, from_currency, to_currency, last_updated):
# 빨간색으로 변경된 부분
#################### 색상(<font>) 및 엔터(<br>)를 넣어 줌 ####################
result_text = f"<font color='red'>{input_value:,.6f}</font> {from_currency}는 <font color='red'>{output_value:,.6f}</font> {to_currency} 입니다."
result_text += f"<br><br>환율: <font color='red'>1</font> {from_currency} = <font color='red'>{rate:,.6f}</font> {to_currency}"
result_text += f"<br>마지막 업데이트: {last_updated}"
self.textEdit.setHtml(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 주요 내용
아래 소스코드에 대한 주요 내용만 설명하겠습니다.
소스 파일 : 5_1.py
값 입력 등의 변경 발생 시 환율을 계산하여 보여줍니다.
소스코드 설명은 아래 화면을 참고 바랍니다.
소스 파일 : 5_2.py
콤보박스가 변경되면 값을 기존 값을 삭제하고, 엔터를 치면 calculate()메소드가 실행되어 환율을 계산 후 textEdit에 뿌려줍니다.
소스코드 설명은 아래 화면을 참고 바랍니다.
소스 파일 : 5_3.py
결과 화면을 좀 더 보기 좋게 하기위하여 색상을 넣고 있습니다.
소스코드 설명은 아래 화면을 참고 바랍니다.
ㅁ 정리
O 우리가 배운 내용
1. 실행버튼을 클릭하지 않고, change이벤트가 발생 시 실행하되, 여기서는 변경 발생 후 1초 후에 실행되도록 시간 딜레이를 주었습니다.
2.위의 경우 여러가지 문제점이 있으므로 시간 딜레이 대신 엔터 이벤트가 발생한 경우 실행되도록 수정해 보고, 눈에 띄도록 환율 계산 결과의 색상을 바꾸어 보았습니다.
오늘은 여기까지이며, 위의 내용이 유익하셨다면, 광고 한번씩만 클릭 부탁드립니다.
감사합니다.
'파이썬 프로젝트 강좌(초급) > 환율 계산기' 카테고리의 다른 글
환율 계산기 만들기 - 6. 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 |