Build a Python GUI Barcode Scanner on Raspberry Pi with Qt PySide6
If you’re aiming to develop a cross-platform GUI application using Python and Qt, your primary options are PyQt and PySide. Both offer Qt bindings for Python, but they differ mainly in licensing: PyQt5 requires either a GPL or a commercial license, while PySide6 is licensed under LGPL, making it more flexible for commercial applications. Given that PySide6 is officially recommended and up-to-date with the latest Qt features, we’ll use it alongside Dynamsoft’s Python Barcode SDK to build a robust GUI barcode reader app for Raspberry Pi.
This article is Part 1 in a 7-Part Series.
- Part 1 - Build a Python GUI Barcode Scanner on Raspberry Pi with Qt PySide6
- Part 2 - How to Build a Cross-Platform GUI Python Barcode and QR Code Reader with PySide6 and Qt Designer
- Part 3 - How to Read QR Codes from Screen Capture in Python with Qt and Dynamsoft Barcode SDK
- Part 4 - How to Integrate a Barcode Scanner in a Django Web App with Python
- Part 5 - How to Build a Python Flet Chat App with Barcode Scanning and Gemini AI
- Part 6 - How to Dockerize a Python Barcode Reader for ARM64 and ARM32 Devices
- Part 7 - ZXing vs ZBar vs Dynamsoft: Python Barcode Reader Comparison with Accuracy and Speed Benchmarks
What you’ll build: A cross-platform Python GUI barcode scanner for Raspberry Pi that reads barcodes from image files and a live webcam stream, using Qt PySide6 for the interface and Dynamsoft Capture Vision SDK for decoding — with barcode detection offloaded to a separate process to keep the UI responsive.

Key Takeaways
- You can build a fully functional Python GUI barcode scanner on Raspberry Pi using Qt PySide6 and Dynamsoft Capture Vision SDK.
- Python threads and
QThreaddo not bypass the GIL for CPU-intensive barcode decoding; Python’smultiprocessingmodule is the correct solution on Raspberry Pi. - The completed application is cross-platform and runs without code changes on Windows, Linux, and macOS.
- Dynamsoft Barcode Reader supports 20+ symbologies including QR Code, Code 128, PDF417, and DataMatrix.
Common Developer Questions
- How do I build a Python barcode scanner GUI for Raspberry Pi?
- Why does my PySide6 Raspberry Pi barcode app freeze or lag during webcam scanning?
- How do I use Python multiprocessing with PySide6 to decode barcodes from a webcam without blocking the UI?
Prerequisites
-
OpenCV
python3 -m pip install opencv-python -
PySide6
python3 -m pip install PySide6 -
Dynamsoft Barcode Reader
python3 -m pip install dynamsoft-capture-vision-bundle -
License: Get a 30-day free trial license for Dynamsoft Barcode Reader.
Step 1: Build the GUI Barcode Reader on Raspberry Pi
Step 1.1: Set Up the UI Widgets
-
Button for Loading Image Files:
Allow users to load images for barcode scanning.
self.btn = QPushButton("Load an image") self.btn.clicked.connect(self.pickFile) def pickFile(self): filename = QFileDialog.getOpenFileName(self, 'Open file', self._path, "Barcode images (*)") if filename is None or filename[0] == '': self.showMessageBox("No file selected") return -
Button for Opening the Live Camera Stream:
Enable live scanning from a connected webcam.
btnCamera = QPushButton("Open camera") btnCamera.clicked.connect(self.openCamera) self.timer = QTimer() self.timer.timeout.connect(self.nextFrameUpdate) def openCamera(self): if not self._cap.isOpened(): self.showMessageBox("Failed to open camera.") return self.timer.start(1000./24) -
Button for Stopping the Camera Stream:
Allow users to stop the live camera stream.
btnCamera = QPushButton("Stop camera") btnCamera.clicked.connect(self.stopCamera) def stopCamera(self): self.timer.stop() -
Label for Displaying Camera Frames and a Text Area for Barcode Decoding Results:
Show the live video feed and display barcode results.
self.label = QLabel() self.label.setFixedSize(self.WINDOW_WIDTH - 30, self.WINDOW_HEIGHT - 160) self.results = QTextEdit() def showResults(self, frame, results): frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) image = QImage(frame, frame.shape[1], frame.shape[0], frame.strides[0], QImage.Format_RGB888) pixmap = QPixmap.fromImage(image) pixmap = self.resizeImage(pixmap) self.label.setPixmap(pixmap) self.results.setText(results)
Step 1.2: Integrate OpenCV for Image and Video Capture
Use OpenCV to handle image loading and capture frames from the webcam:
frame = cv2.imread(filename)
self._cap = cv2.VideoCapture(0)
self._cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
self._cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
ret, frame = self._cap.read()
Step 1.3: Offload Barcode Decoding to a Separate Process
To integrate the barcode decoding API, a straightforward approach would be to invoke the decoding method as soon as we capture a frame:
def nextFrameSlot(self):
ret, frame = self._cap.read()
if not ret:
self.showMessageBox('Failed to get camera frame!')
return
frame, results = self._manager.decode_frame(frame)
self.showResults(frame, results)
However, this method is impractical for use on Raspberry Pi. Barcode scanning is a CPU-intensive task, and if it takes too long, it will block the UI thread, causing performance issues. To address this, we need to run the UI and barcode recognition code in separate threads. Unfortunately, due to Python’s Global Interpreter Lock (GIL), using Python threads won’t provide the desired performance improvements. A potential alternative is to use QThread, which operates similarly to Python threads. Let’s evaluate the performance of QThread with the following implementation:
class WorkerSignals(QObject):
result = Signal(object)
class BarcodeManager(QThread):
def __init__(self, license):
super(BarcodeManager, self).__init__()
self.signals = WorkerSignals()
self._reader = BarcodeReader()
self._reader.init_license(license)
settings = self._reader.get_runtime_settings()
settings.max_algorithm_thread_count = 1
self._reader.update_runtime_settings(settings)
self.frameQueue = Queue(1)
def register_callback(self, fn):
self.signals.result.connect(fn)
def run(self):
while True:
try:
frame = self.frameQueue.get(False, 10)
if type(frame) is str:
break
except:
time.sleep(0.01)
continue
try:
results = self._reader.decode_buffer(frame)
self.signals.result.emit(results)
except BarcodeReaderError as error:
print(error)
Testing shows that QThread does not significantly improve performance. Thus, the most effective solution is to offload barcode decoding to a separate Python Process using the multiprocessing module:
from multiprocessing import Process, Queue
import time
import numpy as np
from dynamsoft_capture_vision_bundle import *
def process_barcode_frame(license, frameQueue, resultQueue):
LicenseManager.init_license('LICENSE-KEY')
cvr_instance = CaptureVisionRouter()
while True:
results = None
try:
frame = frameQueue.get(False, 10)
if type(frame) is str:
break
except:
time.sleep(0.01)
continue
results = cvr_instance.capture(frame, EnumPresetTemplate.PT_READ_BARCODES.value)
try:
resultQueue.put(results, False, 10)
except:
pass
def create_decoding_process(license):
size = 1
frameQueue = Queue(size)
resultQueue = Queue(size)
barcodeScanning = Process(target=process_barcode_frame, args=(license, frameQueue, resultQueue))
barcodeScanning.start()
return frameQueue, resultQueue, barcodeScanning
Step 2: Run the Application on Raspberry Pi
Connect a USB webcam to your Raspberry Pi and run the application:
python3 app.py license.txt

The GUI barcode reader app is not limited to Raspberry Pi—it’s cross-platform and works on Windows, Linux, and macOS as well.
Common Issues & Edge Cases
- Camera not detected on Raspberry Pi: If
cv2.VideoCapture(0)fails, verify the USB webcam is recognized by runningls /dev/video*. Try device index1or2if multiple video devices are present. dynamsoft_capture_vision_bundleinstall fails on ARM: This package requires Python 3.8+ and a 64-bit ARM OS. Raspberry Pi OS Lite (32-bit) is not supported — use Raspberry Pi OS 64-bit.- Barcode decoding freezes the UI: This is caused by Python’s GIL preventing threads from running in parallel. The solution in this tutorial — using
multiprocessing.ProcesswithQueue— is required to keep PySide6 responsive on Raspberry Pi hardware.
Source Code
https://github.com/yushulx/python-barcode-qrcode-sdk/tree/main/examples/official/qt_gui