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;
}
}