Introduction
QR codes are everywhere — from scanning menus to making payments or sharing links. In this tutorial, you will learn how to build a fully functional QR Code Generator web app using Python, Streamlit, and the qrcode library. QR codes pair naturally with image handling — see the Pillow image processing tutorial for the deeper dive.
We will also add options for customization, allowing users to pick custom background and fill colors, adjust the sizing, and download the generated QR code as a PNG file.
> 🎬 Watch the Full Video Tutorial:
> Learn the concepts step-by-step on YouTube: Python PRO Shares Top QR Code Generator Techniques
Prerequisites
Before starting, install the required packages using pip:
pip install streamlit qrcode pillowStep 1: Create the App Script
Create a new file named qr_generator.py and add the following Python code:
import streamlit as st
import qrcode
from PIL import Image
import io
st.set_page_config(page_title="QR Code Generator", page_icon="📷", layout="centered")
st.title("📷 Custom QR Code Generator")
# User Inputs
st.subheader("🔧 Configure Your QR Code")
data = st.text_input("Enter the text or URL for your QR Code:", "https://techwithgalvan.in")
col1, col2 = st.columns(2)
with col1:
fill_color = st.color_picker("Fill Color (QR Pattern)", "#000000")
with col2:
back_color = st.color_picker("Background Color", "#ffffff")
box_size = st.slider("Box Size (Resolution)", min_value=5, max_value=20, value=10)
border = st.slider("Border Thickness", min_value=1, max_value=10, value=4)
if st.button("⚡ Generate QR Code"):
if data:
# Generate QR Code
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=box_size,
border=border,
)
qr.add_data(data)
qr.make(fit=True)
# Create Image
img = qr.make_image(fill_color=fill_color, back_color=back_color)
# Convert image to bytes for display and download
buf = io.BytesIO()
img.save(buf, format="PNG")
byte_im = buf.getvalue()
# Display QR Code
st.image(byte_im, caption="Your Generated QR Code", use_container_width=False)
# Download Button
st.download_button(
label="💾 Download QR Code (PNG)",
data=byte_im,
file_name="qrcode.png",
mime="image/png"
)
else:
st.warning("Please enter some text or a valid URL!")Step 2: Run the Application
Launch your local Streamlit app by executing:
streamlit run qr_generator.pyHow It Works
The qrcode library encodes text into a QR matrix and hands it to Pillow for rendering. The QRCode class takes three meaningful parameters: version (size, or None to auto-fit), error_correction (how much damage a code can survive — ERROR_CORRECT_H survives ~30% damage but stores less data), and box_size (pixel width of each module).
Making the QR auto-size by leaving version as None is the pragmatic choice: the library picks the smallest version that fits your text. The fill/back colors accept any RGB tuple, which is how the app offers custom theming — though high contrast matters more than style, since scanners need the dark modules distinguishable.
The download flow is a pattern worth memorizing: save the PIL image to an in-memory BytesIO buffer, then pass those bytes to st.download_button — no temp files, no filesystem cleanup. The same buffer pattern works in the image uploader app.
Key Concepts Covered
* `qrcode.QRCode()` — Configuration object for determining layout settings (borders, size, error correction level).
* `st.color_picker()` — Allows selecting hex colors through native browser picker.
* `st.download_button()` — Facilitates direct downloads of in-memory files (like bytes objects).
What to Try Next
* Logo Overlay: Learn how to embed a custom image/logo right in the center of the QR code using PIL.
* Dynamic URLs: Generate QR codes dynamically based on user databases.
Common Errors & Fixes
ERROR_CORRECT_L to squeeze in more data.pip install qrcode[pil] installs both.BytesIO buffer first.FAQ
Do QR codes expire?
No — a QR code is just an encoding of your text. It 'expires' only if the URL it points to dies.
What error correction level should I use?
Level M (default, ~15% recovery) suits screens. Use H for print stickers that might get scratched or partially covered.
Can I add a logo to the center?
Yes — paste a resized logo onto the QR with Pillow at level H error correction, keeping the logo under ~20% of the code area. The compositing steps are in the Pillow tutorial.