파이썬 프로젝트 강좌(초급)/환율 계산기

환율 계산기 만들기 - 2.GUI 환율 계산기 - 실행버튼 클릭(한방향)

파기차차 2024. 7. 13. 18:51
728x90
반응형
SMALL

ㅁ 개요

 

O 프로젝트 소개

 

 

 - 이번 글은 이전글([파이썬 프로젝트 강좌(초급)/환율 계산기] - 환율 계산기 만들기 - 1.텍스트 환율 계산기)에 이은 3번째 글로 GUI 빈창을 띄워 보는 것 부터 시작해서, 단계적으로 살을 붙이고 실행버튼을 클릭하면 환율을 계산하는 방법을 알아 보겠습니다. 여기서는 한방향(예: 원화->달러)으로만 환율을 계산하며, 다음 단계에서 양방향으로 환율을 계산하도록 보완합니다.

 

 

 

 

O 완성된 프로그램 실행 화면

 

 

 - 최종 완성된 프로그램의 결과화면은 아래와 같습니다.

 

 

1. 2_1.py 실행 시 아래와 같이 실행되며, 현재는 아무 기능이 없습니다.(실행버튼에 소스 코드를 추가해야 함)

 

 

 

 

 

 

 

2. 2_2.py 실행 시 아래와 같이 실행됩니다.

현재는 (1)lineEdit에 입력값이 숫자인지만 판단하도록 코딩되어 있습니다.

 

 

 

 

 

3. 2_3.py 실행 시 아래와 같이 실행됩니다.

현재는 (1)lineEdit에 입력된 값을 (2)실행하면 (3)실행결과에 환율을 계산하여 보여줍니다.

 

 

 

 

4. 2_4.py 실행 시 아래와 같이 실행됩니다.

현재는 (1)lineEdit에 입력된 값을 (2)실행하면 (3)실행결과에 환율 및 환율정보를 가져온 시간을 함께 표시하여 보여줍니다.

 

 

 

 


 

ㅁ 세부 내용

 

O 완성된 소스

 

소스파일 : 2_1.py

# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic
from PyQt5.QtGui import *


form_class = uic.loadUiType("exchangeRate_2_1.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.pushButton.clicked.connect(self.main)

    def main(self):
        pass

app=QApplication(sys.argv)
window = MyWindow()
window.show()
print("Before event loop")
app.exec_()
print("After event loop")

 

 

소스파일 : 2_2.py

# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic
import os
from PyQt5.QtGui import *
import re

form_class = uic.loadUiType("exchangeRate_2_2.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.pushButton.clicked.connect(self.main)

    def main(self):
        pass

        present_value = self.lineEdit.text()
        print(present_value, type(present_value))
        fromCurrency = self.comboBox.currentText()
        toCurrency = self.comboBox_2.currentText()


        if re.match(r'^-?\d+(?:\.\d+)?$', present_value) :
            print("입력값은 숫자입니다.")
        else:
            print("입력값은 숫자가 아닙니다.")
            self.textEdit.setText("입력값은 숫자가 아닙니다. 숫자를 입력하여 주시기 바랍니다.")

app=QApplication(sys.argv)
window = MyWindow()
window.show()
print("Before event loop")
app.exec_()
print("After event loop")

 

 

소스파일 : 2_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("exchangeRate_2_3.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.pushButton.clicked.connect(self.main)

    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}")
    

    def main(self):
        pass

        present_value = self.lineEdit.text()
        print(present_value, type(present_value))
        fromCurrency = self.comboBox.currentText()
        toCurrency = self.comboBox_2.currentText()

        if re.match(r'^-?\d+(?:\.\d+)?$', present_value) :
            print("입력값은 숫자입니다.")
            
            present_value = float(present_value)  # 문자열을 float로 변환
        
            rate, last_updated = self.get_exchange_rate(fromCurrency, toCurrency)
            print(rate, type(rate), last_updated)

            converted_value = present_value * rate
            print(f"{present_value:.2f} {fromCurrency} 는 {converted_value:.2f} {toCurrency} 입니다.")
            self.textEdit.setText(f"{present_value:.2f} {fromCurrency} 는 {converted_value:.2f} {toCurrency} 입니다.")
        else:
            print("입력값은 숫자가 아닙니다.")
            self.textEdit.setText("입력값은 숫자가 아닙니다. 숫자를 입력하여 주시기 바랍니다.")


app=QApplication(sys.argv)
window = MyWindow()
window.show()
print("Before event loop")
app.exec_()
print("After event loop")

 

 

소스파일 : 2_4.py

# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic
import os
from PyQt5.QtGui import *
import re

import requests
import json
from datetime import datetime


form_class = uic.loadUiType("exchangeRate_2_4.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.pushButton.clicked.connect(self.main)

    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}")
    

    def main(self):

        present_value = self.lineEdit.text()
        print(present_value, type(present_value))
        fromCurrency = self.comboBox.currentText()
        toCurrency = self.comboBox_2.currentText()


        if re.match(r'^-?\d+(?:\.\d+)?$', present_value) :
            print("입력값은 숫자입니다.")
            
            present_value = float(present_value)  # 문자열을 float로 변환
        
            rate, last_updated = self.get_exchange_rate(fromCurrency, toCurrency)
            print(rate, type(rate), last_updated)

            converted_value = present_value * rate
            print(f"{present_value:.2f} {fromCurrency} 는 {converted_value:.2f} {toCurrency} 입니다.")
            
            # 결과 텍스트 설정
            result_text = f"{present_value:,.2f} {fromCurrency}는 {converted_value:,.6f} {toCurrency} 입니다."
            result_text += f"\n\n환율: 1 {fromCurrency} = {rate:,.6f} {toCurrency}"
            result_text += f"\n마지막 업데이트: {last_updated}"
            
            self.textEdit.setText(result_text)

 
        else:
            print("입력값은 숫자가 아닙니다.")
            self.textEdit.setText("입력값은 숫자가 아닙니다. 숫자를 입력하여 주시기 바랍니다.")


app=QApplication(sys.argv)
window = MyWindow()
window.show()
print("Before event loop")
app.exec_()
print("After event loop")

 

 

 

 

 

 

 

 

O 소스 실행 방법

 
 
 - 소스파일 다운로드 후 cmd 또는 파워쉘 등에서 아래와 같이 실행하시기 바랍니다.
 
 > python 2_1.py
 > python 2_2.py
 > python 2_3.py
 > python 2_4.py
 

 

 


 
 

O 주요 내용

 

아래 소스코드에 대한 주요 내용만 설명하겠습니다.

 

 

소스 파일 : 2_1.py

pyqt5를 이용하여 윈도우 창을 띄우는 코드 입니다.

line 8 : qt5로 미리 만들어둔 폼을 사용하기 이해서 form_class 클래스를 만듭니다.

line 10: MyWindow클래스를 만드는데, QMainWindow와 form_class 클래스의 상속을 받아 만듭니다.

line 11~16 : 초기화 함수를 정의하는데, 여기서는 기본적으로 윈도우의 크기와 아이콘 그리고 푸시버튼만 일단 만들어 놓았습니다.

 

 

그 외 자세한 내용은 아래 이전글을 참고하시기 바랍니다.

https://pagichacha.tistory.com/10

 

 

 

 

 

소스 파일 : 2_2.py

lineEdit에 입력한 입력값은 숫자여야 하기때문에 이를 검증하는 코드입니다.

line 24 : lineEdit의 값을 읽어 present_value변수에 담습니다.

line 30 : re(정규표현식)로 입력값이 숫자인지 확인합니다.(자세한 내용은 아래 참조)

 

 

========================================

^ : 문자열의 시작을 나타냅니다.
-? : 마이너스 기호가 선택적으로 있을 수 있음을 나타냅니다. ?는 "0개 또는 1개"를 의미합니다.
\d+ : 하나 이상의 숫자를 나타냅니다. \d는 모든 숫자(0-9)를 의미하고, +는 "1개 이상"을 의미합니다.
(?:\.\d+)? : 소수점과 소수점 이하 숫자를 나타내는 부분입니다.
(?:...) : 캡처하지 않는 그룹을 만듭니다.
\. : 실제 소수점을 나타냅니다.
\d+ : 소수점 이하의 하나 이상의 숫자를 나타냅니다.
전체 그룹 뒤의 ?는 이 부분이 선택적임을 나타냅니다. 즉, 정수도 허용됩니다.
$ : 문자열의 끝을 나타냅니다.
따라서 이 정규 표현식은 다음과 같은 형식의 숫자를 허용합니다:
정수 (예: "123", "-456")
소수 (예: "123.45", "-0.789")
re.match() 함수는 문자열의 시작부터 패턴이 일치하는지 검사합니다. 패턴이 일치하면 Match 객체를 반환하고, 일치하지 않으면 None을 반환합니다.
========================================

 

 

 

 

 

 

소스 파일 : 2_3.py

입력된 값을 실행 시 환율정보를 보여줍니다.

line 16~45 : 이전 글에서 설명한 텍스트 환율계산기 코드 입니다.

 

 

 

 

 

line 53~54 : 콤보박스에 선택된 통화를 변수에 저장합니다.

line 59 : lineEdit에 입력된 값은 기본적으로 string입니다. 따라서 환율로 바꾸기 위해서 float형으로 바꿔줍니다.

line 61 : get_exchange_rate(fromCurrency, toCurrency)메서드를 호출하여 대상 통화의 환율과 최신 업데이트 일자를 받아 옵니다.

line 64 : 환율을 계산합니다.

line 65 : 위에서 계산된 값이 잘 나오는지 print()로 찍어 봅니다.

line 66 : 위에서 계산된 값을 textEdit에 뿌려 줍니다.

 

 

 

 

 

소스 파일 : 2_4.py

다른 부분은 동일하며, textEdit에 결과값을 이뿌게 뿌려주는 부분입니다.

line 68~70 : textEdit에 결과를 보여주기 위해 f스트링을 이용해 문장을 정리합니다.

line 71 : 위에서 정리한 문장을 textEdit에 뿌려줍니다.

 

 

 


 

ㅁ 정리

 

O 우리가 배운 내용

 
 - 오늘은 GUI 빈창을 띄워 보는 것 부터 시작해서, 단계적으로 살을 붙이고 실행버튼을 클릭하여 환율을 계산하는 방법을 알아 보았습니다.
 
 

 

오늘은 여기까지이며, 위의 내용이 유익하셨다면, 광고 한번씩만 클릭 부탁드립니다.

 

 

감사합니다.

728x90
반응형
LIST