Scythe Studio website employs cookies to improve your user experience (Read more)

How to generate barcode in Qt/QML application

Nowadays, everywhere we look, no matter if it’s a real-life shop or web page, we can see these little, simple and useful, black and white rectangles. Barcodes & QR codes are everywhere, with their usefulness proven over the years. That is why we decided to create a custom Qt & QML wrapper for barcode & QR code processing.

In this post, we will show how easy it is to generate and display a barcode and what’s going on behind the scenes in our code.

SCodes – barcode & QR code generation

So, to be able to scan or read a barcode (check out our previous blog post about scanning barcodes) first, you need to generate one. With the help of fantastic ZXing (Zebra Crossing) barcode image processing library (in this case we mean its port to C++) and Qt framework. We, at Scythe Studio, created an easy to use library SCodes which can generate and scan barcodes. It can be paired with QML to help us display our result in a simple way no matter the platform we are on.

Here is a little demo of our app, which you can check out at our GitHub:

QR_genereting_demo

 

ZXing C++ library usage in SCodes

ZXing-C++ library will help us with barcodes at a lower level. It supports reading and generating many formats of codes but here we will focus on 1-dimensional Code 128 and 2-dimensional QR Code and Data Matrix. The difference between them in our application is simply the format property because ZXing takes care of all string-to-image conversion.

The library provides a very simple API:

  1. ZXing::MultiFormatWriter class takes a barcode format as constructor’s argument and lets us set encoding, margin, and ECC level (error correction code level)

  2. We call an encode() method of the class mentioned above with our text content and output image size as arguments

  3. It returns BitMatrix where true == black pixel and false == white pixel of binary barcode image

After we get the bitmap we can process it to image however we like. That’s all there is to it.

The barcode generation

Let’s take a look at the code and how it’s done.

 First we initialize the MultiFormatWriter class with desired options.

int margin = 1;
int eccLevel = 1;
ZXing::BarcodeFormat format = ZXing::BarcodeFormat::CODE_128;
ZXing::MultiFormatWriter writer = ZXing::MultiFormatWriter(format).setMargin(margin).setEccLevel(eccLevel);

Past the first step. Now that we have set up a writer, it’s time to call an encode() method to give us a bitmap we can work with later.

ZXing::Matrix<uint8_t> bitmap;
bitmap = ZXing::ToMatrix<uint8_t>(writer.encode(ZXing::TextUtfEncoding::FromUtf8(“text”), 500, 500));

Our bitmap is ready, so let’s save it as a PNG image. For this, we will use a part of the stb library which is shipped with ZXing.

std::string filepath = “barcode.png”;
stbi_write_png(filepath.c_str(), bitmap.width(), bitmap.height(), 1, bitmap.data(), 0);

And it’s done! We have our barcode image.

 

Code insights – Qt/QML

First, to be able to interact between C++ and QML we need a proper class. It must contain properties of the output image exposed as Q_PROPERTY and a whole class exposed to QML which is done with QML_ELEMENT (available since Qt 5.15.0).

class SBarcodeGenerator: public QQuickItem {

  Q_OBJECT

  Q_PROPERTY(int width MEMBER _width NOTIFY widthChanged)
  Q_PROPERTY(int height MEMBER _height NOTIFY heightChanged)
  Q_PROPERTY(int margin MEMBER _margin NOTIFY marginChanged)
  Q_PROPERTY(int eccLevel MEMBER _eccLevel NOTIFY eccLevelChanged)
  Q_PROPERTY(QString fileName MEMBER _fileName NOTIFY fileNameChanged)
  Q_PROPERTY(ZXing::BarcodeFormat format MEMBER _format)
  Q_PROPERTY(QString extension MEMBER _extension)
  Q_PROPERTY(QString filePath MEMBER _filePath)
  Q_PROPERTY(QString inputText MEMBER _inputText)

  #if(QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
  QML_ELEMENT
  #endif

  …

  public slots: 
    bool process(const QString & inputString);
  …

  signals: 
    void processFinished();

  ...

  private: 
  int _width = 500;
  int _height = 500;
  int _margin = 10;
  int _eccLevel = -1;
  ZXing::BarcodeFormat _format = ZXing::BarcodeFormat::QR_CODE;
  QString _extension = "png";
  QString _fileName = "barcode";
  QString _filePath = "";
  QString _inputText = "";
  ZXing::Matrix < uint8_t > _bitmap = ZXing::Matrix < uint8_t > ();
}

These are the code snippets of our wrapper for displaying purposes. If you want to check out the whole wrapper, head to SCodes repository.

Now for the process function, it’s almost the same code as in case of MultiFormatWriter initialization. Additionally, we also create path, filename and depending on the extension, we save our image. After everything’s done, we emit a processFinished() signal so QML can do its work.

bool SBarcodeGenerator::process(const QString & inputString) {
  if (inputString.isEmpty()) {
    return false;
  }
  else {
    ZXing::MultiFormatWriter writer = ZXing::MultiFormatWriter(_format).setMargin(_margin).setEccLevel(_eccLevel);
    _bitmap = ZXing::ToMatrix < uint8_t > (writer.encode(ZXing::TextUtfEncoding::FromUtf8(inputString.toStdString()), _width, _height));
    _filePath = QDir::tempPath() + "/" + _fileName + "." + _extension;

    if (_extension == "png") {
      stbi_write_png(_filePath.toStdString().c_str(), _bitmap.width(), _bitmap.height(), 1, _bitmap.data(), 0);
    }
    else if (_extension == "jpg" || _extension == "jpeg") {
      stbi_write_jpg(_filePath.toStdString().c_str(), _bitmap.width(), _bitmap.height(), 1, _bitmap.data(), 0);
    }

    emit processFinished();
    return true;
  }
}

Now in the QML part, we start by creating the SBarcodeGenerator object so we can interact with the C++ class. When we hit the button, the barcodeGenerator will start processing our string (in this case it’s a simple “text”). After it finishes a signal is sent and our overwritten default signal handler will change the Image’s container source to the generated image and display it.

ApplicationWindow {
id: root
visible: true  
width: 500  
height: 500

SBarcodeGenerator {
    id: barcodeGenerator
    onProcessFinished: {
        image.source = "file:///" + barcodeGenerator.filePath
    }
}

Button {
    id: generateButton
    onClicked: {
        image.source = ""
        barcodeGenerator.process(qStr(“test”))
    }
}

Image {
    id: image
    anchors: parent
    width: parent.width 
    height: image.width
}
}

It’s as simple as it gets. Really. Of course, these are snippets, and we skipped some trivial parts of the code, so if you want to see complete and more complex application check out our library SCodes with 2 demos for scanning and generating barcodes.

Summary

As you can see generating barcodes with ZXing is pretty straightforward as well as displaying your result in QML. If you have any questions regarding the topic or you want Scythe Studio to develop a solution with barcode support don’t hesitate to contact us!

Latest posts

QML 3D: First impressions main image
QML 3D: First impressions

If we think about it for a minute, it is impossible to imagine an app without a UI. We need […]

26 May 2021
Top 10 Cross-platform apps ideas 2021 main image
Top 10 Cross-platform apps ideas 2021

When developing an application you want it to be as enjoyable for clients as it’s possible, so you take much […]

15 Apr 2021
How tu customise installer behaviour with Qt Installer Framework main image
How tu customise installer behaviour with Qt Installer Framework

In previous posts of this series, we briefly touched on the topic of scripting, while describing how to add custom […]

30 Mar 2021
How to use NFC in Qt/Qml application? main image
How to use NFC in Qt/Qml application?

Have you ever wondered how to use NFC in Qt/Qml application? This blog post will give you a complex overview […]

09 Mar 2021
Low technology stack with Qt: Saved money main image
Low technology stack with Qt: Saved money

When creating a new software, you want the quality to be the highest, while keeping the costs low and delivery […]

08 Feb 2021
How to customize installer UI with Qt Installer Framework main image
How to customize installer UI with Qt Installer Framework

In the previous post you learned the basics of the app deployment process and installer generation. However Qt Installer Framework […]

12 Jan 2021
Deploying app and generating offline installers for Windows Qt Installer Framework tutorial main image
Deploying app and generating offline installers for Windows Qt Installer Framework tutorial

Development is not an only part of product delivering – deployment and maintenance are both equally important parts of the […]

25 Nov 2020
How to interface Qt with Android Java code main image
How to interface Qt with Android Java code

Software development is demanding and often requires us to use languages or solutions that are not part of our main […]

18 Nov 2020
Qt Creator Cheat Sheet main image
Qt Creator Cheat Sheet

Qt Creator Cheat Sheet is a convenient document to improve your familiarity with Qt Creator IDE. The work of every […]

03 Nov 2020
How to track keyboard usage on Windows with Qt in 2020 main image
How to track keyboard usage on Windows with Qt in 2020

There are many use cases when the frequency of user input needs to be tracked. The simple example is a […]

28 Sep 2020