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
- Download the SDK.
- Get a 30-day trial license for free.
- Build the Python barcode extension with C/C++ code:
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.
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