Linux环境下QT中实现二维码生成有两种方法,这两种方法都需要用到开源的代码--qrencode。

第一种方法是下载qrencode源码后,将其移植到目标板子上,然后在程序中包含其路径进行使用;

第二种方法是将qrencode源码添加到自己的程序中,直接调用使用。本文使用的第二种方法进行生成二维码图片。

qrencode是开源的二维码QR码编码库,主要C语言编写的,这样方便移植到各种平台下。

QR Code码特点如图一所示


一、相关参数介绍

//相关参数
/**
 * QRcode class.
 * Symbol data is represented as an array contains width*width uchars.
 * Each uchar represents a module (dot). If the less significant bit of
 * the uchar is 1, the corresponding module is black. The other bits are
 * meaningless for usual applications, but here its specification is described.
 * <pre>
 * MSB 76543210 LSB
 *     |||||||`- 1=black/0=white
 *     ||||||`-- data and ecc code area
 *     |||||`--- format information
 *     ||||`---- version information
 *     |||`----- timing pattern
 *     ||`------ alignment pattern
 *     |`------- finder pattern and separator
 *     `-------- non-data modules (format, timing, etc.)
 * </pre>
 */
typedef struct {
	int version;         ///< version of the symbol
	int width;           ///< width of the symbol
	unsigned char *data; ///< symbol data
} QRcode;

/**
 * Level of error correction.
 */
typedef enum {
	QR_ECLEVEL_L = 0, ///< lowest
	QR_ECLEVEL_M,
	QR_ECLEVEL_Q,
	QR_ECLEVEL_H      ///< highest
} QRecLevel;

/**
 * Encoding mode.
 */
typedef enum {
	QR_MODE_NUL = -1,  ///< Terminator (NUL character). Internal use only
	QR_MODE_NUM = 0,   ///< Numeric mode
	QR_MODE_AN,        ///< Alphabet-numeric mode
	QR_MODE_8,         ///< 8-bit data mode
	QR_MODE_KANJI,     ///< Kanji (shift-jis) mode
	QR_MODE_STRUCTURE, ///< Internal use only
	QR_MODE_ECI,       ///< ECI mode
	QR_MODE_FNC1FIRST,  ///< FNC1, first position
	QR_MODE_FNC1SECOND, ///< FNC1, second position
} QRencodeMode;

//代码中使用的函数
/**
 * Free the instance of QRcode class.
 * @param qrcode an instance of QRcode class.
 */
extern void QRcode_free(QRcode *qrcode);

/**
 * Create a symbol from the string. The library automatically parses the input
 * string and encodes in a QR Code symbol.
 * @warning This function is THREAD UNSAFE when pthread is disabled.
 * @param string input string. It must be NUL terminated.
 * @param version version of the symbol. If 0, the library chooses the minimum
 *                version for the given input data.
 * @param level error correction level.
 * @param hint tell the library how Japanese Kanji characters should be
 *             encoded. If QR_MODE_KANJI is given, the library assumes that the
 *             given string contains Shift-JIS characters and encodes them in
 *             Kanji-mode. If QR_MODE_8 is given, all of non-alphanumerical
 *             characters will be encoded as is. If you want to embed UTF-8
 *             string, choose this. Other mode will cause EINVAL error.
 * @param casesensitive case-sensitive(1) or not(0).
 * @return an instance of QRcode class. The version of the result QRcode may
 *         be larger than the designated version. On error, NULL is returned,
 *         and errno is set to indicate the error. See Exceptions for the
 *         details.
 * @throw EINVAL invalid input object.
 * @throw ENOMEM unable to allocate memory for input objects.
 * @throw ERANGE input data is too large.
 */
extern QRcode *QRcode_encodeString(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive);

二、准备工作

1、准备好Qt

2、下载qrencode动态库(以Ubuntu为例),如果需要依赖其他库请先下载其他库

sudo apt-get install libqrencode-dev

3、在Qt的pro文件当中添加动态库链接

LIBS += -lqrencode

三、不说废话了,直接上代码

#ifndef QRCODELABEL_H
#define QRCODELABEL_H

#include <QLabel>
#include <QPainter>
#include <qrencode.h>
#include <QPaintEvent>

class QRcodeLabel : public QLabel
{
    Q_OBJECT

public:
    explicit QRcodeLabel(QWidget *parent = Q_NULLPTR);
    ~QRcodeLabel();

    void setString(const QString str);
    void setLogo(const QString path);

protected:
    virtual void paintEvent(QPaintEvent *ev);

private:
    QRcode* qrcode;
    QPixmap* image;
    bool logo;

};

#endif // QRCODELABEL_H
#include "QRcodeLabel.h"

QRcodeLabel::QRcodeLabel(QWidget *parent) :
    QLabel(parent)
{
    qrcode = NULL;
}

QRcodeLabel::~QRcodeLabel()
{
    if(qrcode != NULL) {
        QRcode_free(qrcode);
    }
}

void QRcodeLabel::setString(const QString str)
{
    if(qrcode != NULL) {
        QRcode_free(qrcode);
    }
    qrcode = QRcode_encodeString(str.toStdString().c_str(), 2, QR_ECLEVEL_H, QR_MODE_8, 1);
    update();
}

void QRcodeLabel::setLogo(const QString path)
{
    image = new QPixmap(path);
    logo = true;
    update();
}

void QRcodeLabel::paintEvent(QPaintEvent *ev)
{
    Q_UNUSED(ev);
    int width = this->width();
    int height = this->height();
    int qrWidth = qrcode->width > 0 ? qrcode->width : 1 ;
    double scaleX = (double)width / (double)qrWidth ;
    double scaleY = (double)height / (double)qrWidth ;

    QPainter painter(this);
    painter.setBrush(Qt::white);
    painter.setPen(Qt::NoPen);
    painter.drawRect(this->rect());
    painter.setBrush(Qt::black);
    for(int y = 0; y < qrWidth; ++y) {
        for(int x = 0; x < qrWidth; ++x) {
            uchar node = qrcode->data[y*qrWidth + x];
            if(node & 0x01) {
                QRectF rectf(x*scaleX, y*scaleY, scaleX, scaleY);
                painter.drawRects(&rectf, 1);
            }
        }
    }

    if(logo) {
        int logoW = width * 0.2;
        int logoH = height * 0.2;
        QRect rect((width-logoW)/2, (height-logoH)/2, logoW, logoH);
        painter.setPen(QPen(Qt::red, 3));
        painter.drawRect(rect);
        painter.drawPixmap(rect, image->copy());
        logo = false;
    }
}



Logo

更多推荐