参考
原理
- 看参考2
二维码主要构成包括以下几个元素:
定位图案(Position detection pattern):二维码中的三个大正方形用于识别二维码的位置和方向。
对齐图案(Alignment pattern):一些小正方形的集合,用于校正二维码图像在扫描时可能出现的倾斜和变形问题。
- 时序图案(Timing pattern):一条横向和一条纵向的线,表示二维码中的每个模块(Module)是黑色还是白色。时序图案也用于与定位图案和对齐图案配合确定二维码的位置和方向。
- 版本信息(Version information):二维码版本号和纠错等级等信息的编码。
- 数据和纠错编码:具体存储在二维码中的编码信息,包括数据编码和纠错编码。
QRcode *QRcode_encodeString(const char *string, int version,\
QRecLevel level, QRencodeMode hint, int casesensitive)
-string 要转化成二维码的字符串
-version 生成二维码的版本号
-level 纠错能力
-hint 编码模式,包含中文要用QR_MODE_8 ,也就是UTF8
-casesensitive 是否区分大小写
代码
qrcode.h
#ifndef QRCODE_H
#define QRCODE_H
#include <QWidget>
#include "qrencode/qrencode.h"
#include<QString>
#include<QByteArray>
#include<QPainter>
#include<QBrush>
#include<QRectF>
#include<QClipboard>
QT_BEGIN_NAMESPACE
namespace Ui { class QRCODE; }
QT_END_NAMESPACE
class QRCODE : public QWidget
{
Q_OBJECT
public:
QRCODE(QWidget *parent = nullptr);
~QRCODE();
void paintEvent(QPaintEvent *e) override;
private slots:
void on_createPB_clicked();
void on_copyPB_clicked();
private:
Ui::QRCODE *ui;
int size; // 每个小方格大小
int xMargin;//边界
int yMargin;//边界
QPixmap centerIcon;
QImage qrCodeQImage;
QByteArray infoStr;
};
#endif // QRCODE_H
qrcode.cpp
#include "qrcode.h"
#include "ui_qrcode.h"
QRCODE::QRCODE(QWidget *parent)
: QWidget(parent)
, ui(new Ui::QRCODE)
{
ui->setupUi(this);
ui->groupBox->setStyleSheet("color:green");
setWindowTitle("二维码生成器");
setWindowIcon(QIcon(":/icon.ico"));
size=0; // 每个小方格大小
xMargin=0;//边界
yMargin=0;//边界
centerIcon=QPixmap(":/center.png");
infoStr="";
on_createPB_clicked();
}
QRCODE::~QRCODE()
{
delete ui;
}
void QRCODE::paintEvent(QPaintEvent *e)
{
QPainter paint(this);
QBrush brush(Qt::black);
paint.setBrush(brush);
/*
* QRcode *QRcode_encodeString(const char *string, int version,\
QRecLevel level, QRencodeMode hint, int casesensitive)
string 要转化成二维码的字符串
version 生成二维码的版本号
level 纠错能力
hint 编码模式,包含中文要用QR_MODE_8 ,也就是UTF8
casesensitive 是否区分大小写
*/
QRcode *mQRcode=QRcode_encodeString(infoStr.data(),7,QR_ECLEVEL_Q,QR_MODE_8,true);
if(mQRcode==NULL)
return;
size=(this->width()-50)/mQRcode->width;
xMargin= (this->width()/2)-(mQRcode->width*size)/2;
yMargin= (this->height()/2)-(mQRcode->width*size)/2+ui->createPB->height();
unsigned char *poin=mQRcode->data;
QPixmap copyPixmap(QSize(mQRcode->width*size,mQRcode->width*size));
copyPixmap.fill(Qt::transparent); //设置背景透明
QPainter pixPainter(©Pixmap);
pixPainter.setBrush(brush);
for (int x = 0; x < mQRcode->width; x++)
{
for (int y = 0; y < mQRcode->width; y++)
{
if(*poin & 1) // & 按位与,有0则0
{
QRectF r(x*size+xMargin,y*size+yMargin,size,size);
paint.drawRect(r); // 绘制在窗口
QRectF s(x*size,y*size,size,size);
pixPainter.drawRect(s); // 绘制在copyPixmap对象
}
poin++;
}
}
qrCodeQImage = copyPixmap.toImage();
// 绘制中心图片
double scale = 0.23; //中心图片比例
double icon_size = (this->width()-2*xMargin)*scale;
double ix = this->width()/2.0 - icon_size/2.0;
double iy = this->height()/2.0 - icon_size/2.0;
QRect iconR(ix,iy,icon_size,icon_size);
paint.drawPixmap(iconR,centerIcon);
}
void QRCODE::on_createPB_clicked()
{
QString inputStr=ui->lineEdit->text();
if(inputStr.isEmpty())
inputStr="请输入二维码信息";
infoStr = inputStr.toUtf8();
this->update();
}
void QRCODE::on_copyPB_clicked()
{
// 使用QPixmap::copy()函数将矩形框范围内的像素数据拷贝到一张新的QPixmap对象中
//QPixmap qrCodeImage = this->grab().copy(QRect(xMargin,yMargin,this->width()*2,this->width()*2));
// 将新的QPixmap对象转换为QImage类型
//qrCodeQImage = qrCodeImage.toImage();
// 将QImage设置到剪贴板中
QClipboard *clipboard = QApplication::clipboard();
clipboard->setImage(qrCodeQImage);
}