Skip to main content

Python - PyQt Desktop App

Sham Sui Po, Hong Kong

Github Repository

Setup

pip install PyQt6

Hello World

Create a simple Layout in Qt6:

from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout
from PyQt6.QtWidgets import QLabel, QPushButton, QLineEdit

app = QApplication([])
window = QWidget()
window.setWindowTitle('PyQt6 Application')

layout = QVBoxLayout()

text = QLineEdit()

layout.addWidget(text)

window.setLayout(layout)
window.show()
app.exec()

Python - PyQt Desktop App

Signals

State is exchanged in Qt by "signals":

def make_it_so():
input_text = text.text()
output_label.setText(input_text)

btn = QPushButton('Make it so!')
layout.addWidget(btn)
btn.clicked.connect(make_it_so)

output_label = QLabel('')
layout.addWidget(output_label)

When the button is clicked it triggers a function that then pushes the state - text input - of the input field to an label widget.

Working with User Inputs

Once we have the user input from our text widget we can add some functionality to it - for example turning input strings into URL-safe base64 representations:

Python - PyQt Desktop App

from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout
from PyQt6.QtWidgets import QLabel, QPushButton, QLineEdit

import base64

# Add functions - what do you want to do with the user input

def to_base64():
input_text = text_encode.text()
encoded_bytes = base64.urlsafe_b64encode(input_text.encode("utf-8"))
encoded_text = str(encoded_bytes, "utf-8")
output_encode.setText("Encoded String: " + encoded_text)

def from_base64():
input_text = text_decode.text()
decoded_bytes = base64.urlsafe_b64decode(input_text.encode("utf-8"))
decoded_text = str(decoded_bytes, "utf-8")
output_decode.setText("Decoded String: " + decoded_text)

# App scaffolding

app = QApplication([])
window = QWidget()
window.setWindowTitle('base64 de/encoder')
layout = QVBoxLayout()

# Encode string to base64

text_encode = QLineEdit()
layout.addWidget(text_encode)

btn = QPushButton('base64 Encode')
layout.addWidget(btn)
btn.clicked.connect(to_base64)

output_encode = QLabel('')
layout.addWidget(output_encode)

# Decode string from base64

text_decode = QLineEdit()
layout.addWidget(text_decode)

btn = QPushButton('base64 Decode')
layout.addWidget(btn)
btn.clicked.connect(from_base64)

output_decode = QLabel('')
layout.addWidget(output_decode)

## Execute

window.setLayout(layout)
window.show()
app.exec()

Web Scraping

Using Beautiful Soup to scrape information from the web.

Python - PyQt Desktop App

Calculate the price of an INSTAR camera by scraping the latest prize from the INSTAR web shop:

from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout
from PyQt6.QtWidgets import QLabel, QPushButton, QLineEdit

from bs4 import BeautifulSoup
import requests

def get_prize():
url = f'https://www.instar.com/produkte/wlan-aussenkameras-poe-ip-kameras-wetterfeste-netzwerkkameras-outdoor-uberwachungskameras/in-9408-2k-serie-wlan-uberwachungskamera-ai-objekterkennung-apple-homekit-mqtt-sftp-nachtsicht/in-9408-2k-poe-weiss-ip-kamera.html'
content = requests.get(url).text
soup = BeautifulSoup(content, 'html.parser')
prize = soup.find("span", class_="price").get_text()
prize_intl = prize.replace(',', '.')
prize_float = float(prize_intl[:-2])

return prize_float


def calc_value():
number = float(number_input.text())
prize = get_prize()
calculated_value = str(number * prize)
number_output.setText(calculated_value)

# App scaffolding

app = QApplication([])
window = QWidget()
window.setWindowTitle('Price Calculator - INSTAR IN-9408 2k+')
layout = QVBoxLayout()

# Encode string to base64

number_input = QLineEdit()
layout.addWidget(number_input)

btn = QPushButton('Get Price')
layout.addWidget(btn)
btn.clicked.connect(calc_value)

number_output = QLabel('')
layout.addWidget(number_output)

## Execute

window.setLayout(layout)
window.show()
app.exec()

Advanced UI Elements

Using Dropdown menus:

currencies = ['USD','EUR','GBP','CNY']

select_inCurrency = QComboBox()
select_inCurrency.addItems(currencies)
layout.addWidget(select_inCurrency)

select_outCurrency = QComboBox()
select_outCurrency.addItems(currencies)
layout.addWidget(select_outCurrency)

Advanced Layouts

Python - PyQt Desktop App

from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout
from PyQt6.QtWidgets import QLabel, QPushButton, QLineEdit, QComboBox

from bs4 import BeautifulSoup
import requests

def get_conversion(in_currency, out_currency):
url = f'https://www.x-rates.com/calculator/?from={in_currency}&to={out_currency}&amount=1'
content = requests.get(url).text
soup = BeautifulSoup(content, 'html.parser')
rate = soup.find("span", class_="ccOutputRslt").get_text()
rate_float = float(rate[:-4])

return rate_float

def calc_value():
number = float(number_input.text())
in_currency = select_inCurrency.currentText()
out_currency = select_outCurrency.currentText()
rate = get_conversion(in_currency, out_currency)
calculated_value = str(number * rate)
message = f'{number} {in_currency} is {calculated_value} {out_currency}'
number_output.setText(message)

# App scaffolding

app = QApplication([])
window = QWidget()
window.setWindowTitle('Currency Converter')

layoutMain = QVBoxLayout()
layoutContainer = QHBoxLayout()
layoutMain.addLayout(layoutContainer)

layoutLeftBox = QVBoxLayout()
layoutContainer.addLayout(layoutLeftBox)
layoutRightBox = QVBoxLayout()
layoutContainer.addLayout(layoutRightBox)


# Select Currencies

currencies = ['USD','EUR','GBP','CNY']

select_inCurrency = QComboBox()
select_inCurrency.addItems(currencies)
layoutLeftBox.addWidget(select_inCurrency)

select_outCurrency = QComboBox()
select_outCurrency.addItems(currencies)
layoutLeftBox.addWidget(select_outCurrency)

# Convert to Target Currency

number_input = QLineEdit()
layoutRightBox.addWidget(number_input)

btn = QPushButton('Convert')
layoutMain.addWidget(btn)
btn.clicked.connect(calc_value)

number_output = QLabel('')
layoutRightBox.addWidget(number_output)

## Execute

window.setLayout(layoutMain)
window.show()
app.exec()