DEV Community

Professor लला
Professor लला

Posted on

Build a QR Code Generator with Python and KivyMD

As of today, over eighty-five (85) percent of websites + applications utilize QR codes to quickly share links, contact information, location address, restaurant menus, and other quick event details. Today we will create a QR Code Generator from scratch with Python!

We will use KivyMD a library that makes python app looks like a modern Android or iOS app using Material Design.

QR codes are Quick response code are one of the easiest and fastest way to share any information with other people, we see Qr codes in most of around us we see in restaurants, railway tickets, doing payments.

Why KivyMD?

It is standard python apps can look a bit “old school”. KivyMD gives us beautiful text fields, buttons, and layouts with very little code.

What We Need

Before we start, we need to install two main tools:
KivyMD: for user interface.
QRCode: to create the actual QR patterns.

Step 1: Install the Requirements

Run this code in terminal or command prompt

pip install kivymd qrcode pillow

Step 2: Import the Libraries

Create a new file named QRGeneratorApp.py and start by importing the necessary tools.

from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.core.image import Image as CoreImage
import qrcodefrom io 
import BytesIOimport os

Enter fullscreen mode Exit fullscreen mode

## Step 3: Design the UI (The KV String)

We use the KV Language to design the app. This is a declarative way to build the interface. We need a text field for input, two buttons (Generate and Download), and an image area to show the result.

KV = '''
MDScreen:
    md_bg_color: app.theme_cls.bg_light

    MDBoxLayout:
        orientation: 'vertical'
        spacing: "20dp"
        padding: "20dp"
        adaptive_height: True
        pos_hint: {"center_x": .5, "center_y": .5}

        MDLabel:
            text: "QR Code Generator"
            halign: "center"
            font_style: "H4"
            bold: True
            theme_text_color: "Primary"

        MDTextField:
            id: user_input
            hint_text: "Enter URL or Text"
            mode: "outlined"
            size_hint_x: .8
            pos_hint: {"center_x": .5}

        MDBoxLayout:
            orientation: 'horizontal'
            spacing: "10dp"
            adaptive_size: True
            pos_hint: {"center_x": .5}

            MDRaisedButton:
                text: "GENERATE"
                on_release: app.generate_qr(user_input.text)

            MDRaisedButton:
                id: download_btn
                text: "DOWNLOAD"
                md_bg_color: .2, .7, .2, 1 
                disabled: True 
                on_release: app.download_qr()

        Image:
            id: qr_display
            size_hint: None, None
            size: "250dp", "250dp"
            pos_hint: {"center_x": .5}
'''


Enter fullscreen mode Exit fullscreen mode

Step 4: Create the App Logic

To reuse the button clicks, we'll have to make a class in Python that will allow the stoner to perform certain tasks through buttons and will interact with the illustration operation we are erecting, which utilizes the Kivy Framework to give a means for druggies to produce QR canons from their entries.

Once a stoner clicks the Generate button, Kivy will take the textbook that was written in the Text Input contrivance and produce QR law( s). Kivy will also give the druggies with QR canons via the illustration operation's GUI.

The button labeled Download will not change color until at least one QR code has been generated through the click of the Generate button. Once QR code(s) have been created by clicking the Generate button one or more times the Download button will allow users to save the QR code generated(s) in PNG format to their current working folder.

class QRGeneratorApp(MDApp):
    current_qr_img = None  # To store the image in memory

    def build(self):
        self.theme_cls.primary_palette = "DeepPurple"
        return Builder.load_string(KV)

    def generate_qr(self, data):
        if not data.strip():
            return

        # 1. Create the QR object
        qr = qrcode.QRCode(version=1, box_size=10, border=2)
        qr.add_data(data)
        qr.make(fit=True)

        # 2. Store as PIL image
        self.current_qr_img = qr.make_image(fill_color="black", back_color="white")

        # 3. Convert to Kivy Texture for the UI
        buffer = BytesIO()
        self.current_qr_img.save(buffer, format='PNG')
        buffer.seek(0)
        core_img = CoreImage(buffer, ext='png')
        self.root.ids.qr_display.texture = core_img.texture

        # 4. Enable Download Button
        self.root.ids.download_btn.disabled = False

    def download_qr(self):
        if self.current_qr_img:
            file_name = "my_qr_code.png"
            self.current_qr_img.save(file_name)
            print(f"Saved successfully as {file_name}")

if __name__ == "__main__":
    QRGeneratorApp().run()



Enter fullscreen mode Exit fullscreen mode

Step 5: Run and Test

Just type in a web address like https// google.com, hit Generate, and your QR law pops up! also, click Download to save it and use it still you want. Easy peasy!

The Complete Code
Here is the full script. Save this as QRGeneratorApp.py and run it!

from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.core.image import Image as CoreImage
import qrcode
from io import BytesIO
import os

KV = '''
MDScreen:
    md_bg_color: app.theme_cls.bg_light

    MDBoxLayout:
        orientation: 'vertical'
        spacing: "20dp"
        padding: "20dp"
        adaptive_height: True
        pos_hint: {"center_x": .5, "center_y": .5}

        MDLabel:
            text: "QR Code Generator"
            halign: "center"
            font_style: "H4"
            bold: True
            theme_text_color: "Primary"

        MDTextField:
            id: user_input
            hint_text: "Enter URL or Text"
            mode: "outlined"
            size_hint_x: .8
            pos_hint: {"center_x": .5}

        MDBoxLayout:
            orientation: 'horizontal'
            spacing: "10dp"
            adaptive_size: True
            pos_hint: {"center_x": .5}

            MDRaisedButton:
                text: "GENERATE"
                on_release: app.generate_qr(user_input.text)

            MDRaisedButton:
                id: download_btn
                text: "DOWNLOAD"
                md_bg_color: .2, .7, .2, 1  # Green color
                disabled: True  # Disabled until a QR is made
                on_release: app.download_qr()

        Image:
            id: qr_display
            size_hint: None, None
            size: "250dp", "250dp"
            pos_hint: {"center_x": .5}
'''

class QRGeneratorApp(MDApp):
    # Variable to store the image object in memory
    current_qr_img = None

    def build(self):
        self.theme_cls.primary_palette = "DeepPurple"
        return Builder.load_string(KV)

    def generate_qr(self, data):
        if not data.strip():
            return

        qr = qrcode.QRCode(version=1, box_size=10, border=2)
        qr.add_data(data)
        qr.make(fit=True)

        # Store the PIL image object so we can save it later
        self.current_qr_img = qr.make_image(fill_color="black", back_color="white")

        # Convert to texture for display
        buffer = BytesIO()
        self.current_qr_img.save(buffer, format='PNG')
        buffer.seek(0)

        core_img = CoreImage(buffer, ext='png')
        self.root.ids.qr_display.texture = core_img.texture

        # Enable the download button
        self.root.ids.download_btn.disabled = False

    def download_qr(self):
        if self.current_qr_img:
            # Save the file as 'my_qr_code.png' in the same folder as the script
            file_name = "my_qr_code.png"
            self.current_qr_img.save(file_name)
            print(f"Saved successfully as {file_name}")

if __name__ == "__main__":
    QRGeneratorApp().run()
Enter fullscreen mode Exit fullscreen mode

Conclusion

Stupendous job! You've made across-platform app that works. Just type in your favorite website and click generate.

Top comments (0)