How to Build Python Barcode Apps with Qt on Windows

Qt for Python enables developers to quickly create GUI apps on Windows, Linux and macOS with one codebase. In this article, I will share how to build a Python barcode reader with Qt on Windows. Since Dynamsoft Barcode Reader SDK is also cross-platform, it is easy for you to reuse the sample code on Linux and macOS.

Installing Qt for Python on Windows

To install Qt for Python on Windows, you can either download a .whl file or run the command:

pip install pyside2

When using Python 3.6, I got the following error message:

Error:
Traceback (most recent call last):
File "test2.py", line 3, in <module>
from PySide2.QtWidgets import (QApplication, QLabel, QPushButton, QVBoxLayout, QWidget)
ImportError: DLL load failed: The specified procedure could not be found.

My workaround is to install Python 3.7 instead.

Dynamsoft Barcode Reader

python setup.py build install

A Simple Python Barcode Reader with Windows GUI

Qt designer

If you feel inconvenient to build UI programmatically, you can use Qt designer which is located at Python37\Lib\site-packages\PySide2\designer.exe.

Qt designer

After designing the UI by simply dragging the widgets, you can save the project to a *.ui file.

Next, convert the *.ui file to Python code with E:\Programs\Python\Python37\Scripts\pyside2-uic.exe:

pyside2-uic -x *.ui -o ui.py

Python barcode reader with Windows UI elements

We can quickly set up an app skeleton by reading the Qt for Python homepage.

My UI contains a button, a label, and a text area:

  • Button: pop up a system dialog to load image files from local disks.
  • Label: display the loaded images.
  • Text area: show barcode results.

Here is the code snippet:

import sys
from PySide2.QtGui import QPixmap

from PySide2.QtWidgets import QApplication, QLabel, QPushButton, QVBoxLayout, QWidget, QFileDialog, QTextEdit, QSizePolicy
from PySide2.QtCore import Slot, Qt, QStringListModel, QSize

import dbr
import os

class UI_Window(QWidget):

    def __init__(self):
        QWidget.__init__(self)

        # The default barcode image.
        dir_path = os.path.dirname(os.path.realpath(__file__))
        filename = os.path.join(dir_path, 'image.tif')

        # Create a layout.
        layout = QVBoxLayout()

        # Add a button
        self.btn = QPushButton("Load an image")
        self.btn.clicked.connect(self.pickFile)
        layout.addWidget(self.btn)

        # Add a label
        self.label = QLabel()
        self.label.setFixedSize(640, 640)
        pixmap = self.resizeImage(filename)
        self.label.setPixmap(pixmap)
        layout.addWidget(self.label)

        # Add a text area
        self.results = QTextEdit()
        self.readBarcode(filename)
        layout.addWidget(self.results)

        # Set the layout
        self.setLayout(layout)
        self.setWindowTitle("Dynamsoft Barcode Reader")
        self.setFixedSize(800, 800)

Connect the button to a click event:

def pickFile(self):
        # Load an image file.
        filename = QFileDialog.getOpenFileName(self, 'Open file',
                                               'E:\Program Files (x86)\Dynamsoft\Barcode Reader 6.4.1\Images', "Barcode images (*)")
        # Show barcode images
        pixmap = self.resizeImage(filename\[0\])
        self.label.setPixmap(pixmap)

        # Read barcodes
        self.readBarcode(filename\[0\])

Scale the loaded image to fit into the label:

def resizeImage(self, filename):
        pixmap = QPixmap(filename)
        lwidth = self.label.maximumWidth()
        pwidth = pixmap.width()
        lheight = self.label.maximumHeight()
        pheight = pixmap.height()

        wratio = pwidth * 1.0 / lwidth
        hratio = pheight * 1.0 / lheight

        if pwidth > lwidth or pheight > lheight:
            if wratio > hratio:
                lheight = pheight / wratio
            else:
                lwidth = pwidth / hratio

            scaled_pixmap = pixmap.scaled(lwidth, lheight)
            return scaled_pixmap
        else:
            return pixmap

Call barcode decoding method and then update the text area with the returned results:

def readBarcode(self, filename):
        dbr.initLicense("<Your License>")
        results = dbr.decodeFile(filename, 0x3FF | 0x2000000 | 0x4000000 | 0x8000000 | 0x10000000)
 
        out = ''
        index = 0
        for result in results:
            out += "Index: " + str(index) + "\n"
            out += "Barcode format: " + result[0] + '\n'
            out += "Barcode value: " + result[1] + '\n'
            out += '-----------------------------------\n'
            index += 1
 
        self.results.setText(out)

Run the app:

python barcode-reader.py

Qt Python barcode reader

Source Code

https://github.com/yushulx/python/tree/master/examples/qt