7.9 KiB
ZXing-C++ Qt Wrapper
A header-only Qt wrapper for the ZXing-C++ barcode library, providing idiomatic Qt APIs for barcode reading and writing.
Features
- Header-only: Just include
ZXingQt.h - Qt-style API: Uses Qt types (
QString,QImage,QByteArray, etc.) - Multiple input formats: Read from
QImage,QVideoFrame - QML integration: Ready-to-use QML components
- Signal/slot support: Asynchronous barcode reading with Qt signals
- Video streaming: Built-in support for real-time camera processing
Basic Usage
Reading Barcodes
Simple Function API
#include "ZXingQt.h"
using namespace ZXingQt;
// Read from QImage
for (const auto& barcode : ReadBarcodes(QImage("input.png"))) {
qDebug() << "Text:" << barcode.text();
qDebug() << "Format:" << barcode.format();
}
QObject-based API with Signals
BarcodeReader reader;
reader.setFormats({BarcodeFormat::QRCode, BarcodeFormat::DataMatrix});
reader.setTryRotate(true);
reader.setTryInvert(false);
reader.setTextMode(TextMode::HRI);
QObject::connect(&reader, &BarcodeReader::foundBarcodes,
[](const QList<Barcode>& barcodes) {
for (const auto& barcode : barcodes)
qDebug() << "Found:" << barcode.text();
});
QObject::connect(&reader, &BarcodeReader::foundNoBarcodes,
[]() {
qDebug() << "No barcodes found";
});
QImage image("barcode.png");
reader.readAsync(image); // reads barcodes in background thread and emits signals
Writing Barcodes
Create Barcode from Text
using namespace ZXingQt;
// Simple creation
auto barcode = Barcode::fromText("Hello World", BarcodeFormat::QRCode, "ecLevel=H");
// Save as image
QImage image = barcode.toImage(WriterOptions().scale(4));
image.save("qrcode.png");
// Export as SVG
QString svg = barcode.toSVG();
Create Barcode from Binary Data
QByteArray data = getMyBinaryData();
auto barcode = Barcode::fromBytes(data, BarcodeFormat::DataMatrix);
barcode.toImage().save("datamatrix.png");
Working with Video Streams
Qt 6 Multimedia Integration
#include <QVideoSink>
#include <QMediaCaptureSession>
BarcodeReader reader;
reader.setFormats({BarcodeFormat::AllReadable});
connect(&reader, &BarcodeReader::foundBarcodes, this, &MyClass::onBarcodesFound);
// Connect to video sink
QVideoSink* videoSink = new QVideoSink(this);
reader.setVideoSink(videoSink);
// Set up camera
QMediaCaptureSession session;
session.setVideoOutput(videoSink);
// ... configure camera and start
See ZXingQtCamReader.cpp for a complete camera reader example with GUI.
Barcode Properties
The Barcode class provides:
barcode.isValid() // Check if barcode was successfully read
barcode.format() // BarcodeFormat enum
barcode.symbology() // BarcodeFormat enum (normalized format)
barcode.text() // Decoded text content
barcode.text(TextMode) // Decoded text with specific mode (Plain, ECI, HRI, Escaped, Hex, HexECI)
barcode.bytes() // Raw byte data
barcode.bytesECI() // Bytes with ECI encoding
barcode.contentType() // ContentType enum (Text, Binary, Mixed, GS1, ISO15434, UnknownECI)
barcode.hasECI() // Check if barcode has ECI
barcode.error() // Error information (type, message, location)
barcode.position() // Quadrilateral position in image (topLeft, topRight, bottomRight, bottomLeft, center)
barcode.orientation() // Orientation in degrees
barcode.isMirrored() // Check if barcode is mirrored
barcode.isInverted() // Check if barcode is inverted
barcode.symbologyIdentifier() // ISO/IEC 15424 symbology identifier
barcode.sequenceSize() // Total number of symbols in structured append sequence
barcode.sequenceIndex() // Index of this symbol in sequence
barcode.sequenceId() // Parity/checksum data for sequence
barcode.isLastInSequence() // Check if this is the last symbol in sequence
barcode.isPartOfSequence() // Check if this is part of a structured append sequence
barcode.extra(key) // Get extra metadata by key
barcode.lineCount() // Number of lines (for linear codes)
barcode.symbol() // Get symbol image (1 pixel per module)
barcode.toImage(options) // Convert to QImage (for writing)
barcode.toSVG(options) // Export as SVG (for writing)
Barcode Formats
Use the BarcodeFormat enum for format specification:
BarcodeFormat::QRCode
BarcodeFormat::DataMatrix
BarcodeFormat::EAN13
BarcodeFormat::Code128
BarcodeFormat::PDF417
BarcodeFormat::Aztec
// ... and many more
// Special groups, usable when reading barcodes
BarcodeFormat::AllLinear // All 1D barcodes
BarcodeFormat::AllMatrix // All 2D barcodes (without the stacked ones)
BarcodeFormat::AllReadable
// ... and more
To and from string conversion:
BarcodeFormat format = BarcodeFormatFromString("qrcode"); // case insensitive
QString name = ToString(format); // == "QR Code"
QML Integration
Make sure QT_QML_LIB is defined when including ZXingQt.h to enable and automatically registering the QML support.
import ZXing 1.0
Item {
BarcodeReader {
id: reader
formats: [ZXing.QRCode, ZXing.DataMatrix]
tryRotate: true
onFoundBarcodes: function(barcodes) {
console.log("Found", barcodes.length, "barcode(s)")
console.log("First text:", barcodes[0].text)
}
onFoundNoBarcodes: {
console.log("No barcodes found")
}
}
// Connect to video source
Camera {
id: camera
}
VideoOutput {
source: camera
Component.onCompleted: {
reader.videoSink = videoSink
}
}
}
See the ZXingQmlReader example program.
BarcodeReader Properties
The BarcodeReader class provides the following configurable properties:
reader.setFormats(formats) // BarcodeFormats to scan for
reader.setTextMode(mode) // Text decoding mode (Plain, ECI, HRI, Escaped, Hex, HexECI)
reader.setTryRotate(bool) // Try rotating image for better detection
reader.setTryHarder(bool) // Try harder to detect barcodes (slower)
reader.setTryInvert(bool) // Try inverting colors
reader.setTryDownscale(bool) // Try downscaling large images
reader.setIsPure(bool) // Assume image contains only a pure barcode
reader.setReturnErrors(bool) // Return failed reads with error info
reader.setMaxThreadCount(int) // Maximum worker threads for async processing
Performance Tips
- Limit formats: Only enable formats you actually need
- Avoid tryHarder: Use only when necessary (significantly slower)
- Threading: The
BarcodeReaderclass can process input asynchronously (see alsomaxThreadCount) - Frame skipping: When processing video frames and all threads from the pool are busy, the frame is dropped
Building
Add to your Qt project:
# .pro file
INCLUDEPATH += path/to/zxing-cpp-install-root/include
LIBS += -lZXing # or link statically
# Enable multimedia support
QT += multimedia
Or with CMake:
find_package(Qt6 COMPONENTS Core Gui Multimedia REQUIRED)
find_package(ZXing REQUIRED)
target_link_libraries(myapp
Qt6::Core
Qt6::Gui
Qt6::Multimedia
ZXing::ZXing
)
To build the demo programs like ZXingQtCamReader, set cmake config variable ZXING_EXAMPLES_QT=ON.
Note on Qt Meta-Object Compiler (moc): If ZXingQt.h is located outside your project directory (e.g., in a system include path), Qt's automoc may not detect the Q_OBJECT classes in the header. To fix this, add the following line at the end of your .cpp file that uses BarcodeReader or other Qt classes from ZXingQt.h:
#include "moc_ZXingQt.cpp"
This explicitly includes the moc-generated file, ensuring proper signal/slot functionality without requiring CMake workarounds.