In this exercise, we will be building a simple desktop application to look up today’s currency exchange rates using PyQt5 and Python.

This tutorial is intended for intermediate Python developers. For beginners/inexperienced Python developers, you can benefit greatly as well and also get a feel of building a complete desktop app from scratch.


Buy Me a Coffee? Your support is much appreciated!
PayPal Me: https://www.paypal.me/jiejenn/5
Venmo: @Jie-Jenn





Things we will be learning:

  1. Make a simple REST API call to retrieve dataset
  2. Build a desktop application based on PyQt5 framework
  3. Create classes.

Required External Packages:

  1. requests library (pip install requests)
  2. PyQt5 framework library (pip install PyQt5)

app.py

import sys
import json
from USD_ExchangeRate import CurrencyConverter
from PyQt5.QtWidgets import QApplication, QWidget, QComboBox, QTextEdit, QLineEdit, QPushButton, QLabel, \
                            QVBoxLayout, QHBoxLayout, \
                            QDesktopWidget
from PyQt5.QtGui import QFont, QIcon

class AppDemo(QWidget):
    def __init__(self, rates):
        super().__init__()
        self.rates = rates
        self.setWindowTitle('USD Currency Converter')
        self.setWindowIcon(QIcon('Money-wallet.ico'))
        self.setFixedSize(600, 200)

        currencyList = ['CAD', 'EUR', 'JPY', 'THB', 'VND', 'TWD']
        timestamp = self.rates['timestamp']
        fnt = QFont('Open Sans', 12)


        mainLayout = QVBoxLayout()

        label_timestamp = QLabel("<font size=5><b>Last updated {0} </font>".format(timestamp))

        self.comboCurrencyList = QComboBox()
        self.comboCurrencyList.setFont(fnt)
        self.comboCurrencyList.setFixedHeight(50)

        self.comboCurrencyList.addItems(currencyList)
        self.comboCurrencyList.currentIndexChanged.connect(self.lookupCurrencyRate)

        self.outputField = QTextEdit()
        self.outputField.setFont(fnt)

        self.lookupCurrencyRate()

        mainLayout.addWidget(label_timestamp)
        mainLayout.addWidget(self.comboCurrencyList)
        mainLayout.addWidget(self.outputField)
        self.setLayout(mainLayout)

    def lookupCurrencyRate(self):
        currencyRates = self.rates['quotes']
        targetCurrency = self.comboCurrencyList.currentText()
        currencyPair = 'USD' + targetCurrency
        exchangeRate = currencyRates[currencyPair]

        self.outputField.setText('$1 USD = {0} {1}'.format(exchangeRate, targetCurrency))

def main():
    API_KEY = 'Your API Access Key'
    c1 = CurrencyConverter(API_KEY)

    global currency_rates
    currency_rates = c1.requestCurrency()

    if currency_rates is None:
        sys.exit()

if __name__ == '__main__':
    main()

    app = QApplication(sys.argv)
    demo = AppDemo(currency_rates)
    demo.show()
    sys.exit(app.exec_())



exchange_rate.py

import json
from datetime import datetime
import requests

class CurrencyConverter:
    base_url = 'http://api.currencylayer.com/live'

    def __init__(self, API_KEY):
        self.API_KEY = API_KEY

    def requestCurrency(self):
        params = {'access_key': self.API_KEY}
        response = requests.get(CurrencyConverter.base_url, params=params)
        response_json = json.loads(response.content)
        if response.status_code != 200:
            print('Failed to import currencies')
            print(response.reason)
            return None
        elif not response_json['success']:
            print('Failed to import currencies')
            print(response_json['error']['info'])
            return None
        else:
            timestamp = datetime.fromtimestamp(response_json['timestamp']).strftime('%m-%d-%Y')  
            base_currency = response_json['source']
            quotes = response_json['quotes']
            return {'base': base_currency, 'timestamp': timestamp, 'quotes': quotes}