C++使用QRcode生成二维码
很幸运您搜索到本文章,希望对您有帮助
今天突然想了解下二维码的算法和原理,并且做一个用第三方开源库生成二维码的工具,了解一下第三方库的调用接口。
环境搭建
1.Qt界面库开发环境,使用的vs2013+Qt5.6-win32。
2.libqrencode库,生成二维码的第三方库。
3.libqrencode,通过CMake进行编译,编译过程中需要libopt,libpng,libiconv支持。(这些支持库都是给工程中的qrencode.exe使用的,它是官方提供的一个demo)
vs2013工程生成Qt应用程序实例
1.使用libqrencode库
使用静态库比较简单,只需要拷贝生成的libqrencode.lib和源码中的qrencode.h两个文件到你的项目中。然后
配置属性 --> C/C++ --> 常规 --> 附加包含目录,加入qrencode.h所在路径,
配置属性 --> 链配置属性 --> 链接器 --> 常规 --> 附加库目录,加入libqrencode.lib所在路径
配置属性 --> 链配置属性 --> 链接器 --> 输入 --> 附加依赖项,加入libqrencode.lib
2.生成二维码展示类"QRWidget",cpp文件内容如下:
#include "QRWidget.h"
#include "qrencode.h"
#include <QPainter>
QRWidget::QRWidget(QWidget *parent)
: QWidget(parent)
, mRQData(nullptr)
, mWidth(0)
, mColor(Qt::white)
{
mRQData = new unsigned char[177 * 177];
}
QRWidget::~QRWidget()
{
if (mRQData != nullptr){
delete[] mRQData;
mRQData = nullptr;
}
}
void QRWidget::SetData(const char* pData)
{
if (pData == nullptr){
return;
}
auto qr = QRcode_encodeString(pData, 1, QR_ECLEVEL_L, QR_MODE_8, true);
if (qr == nullptr){
return;
}
Q_ASSERT(qr->width > 0 && qr->width <= 177);
/// <可使用自旋锁,控制刷新内存泄漏TODO:暂未实现>
mWidth = 0;
memcpy(mRQData, qr->data, qr->width*qr->width);
mWidth = qr->width;
QRcode_free(qr);
}
void QRWidget::paintEvent(QPaintEvent* ev)
{
__super::paintEvent(ev);
if (mWidth == 0){
return;
}
auto nW = this->geometry().width();
auto nH = this->geometry().height();
auto nWH = nW > nH ? nH : nW;
/// <画背景>
QPainter painter(this);
QColor background(mColor);
painter.setBrush(background);
painter.setPen(Qt::NoPen);
painter.drawRect(0, 0, nW, nH);
/// <画二维码>
QColor foreground(Qt::black);
painter.setBrush(foreground);
const int qr_width = mWidth > 0 ? mWidth : 1;
double scale_x = (nWH-23) / qr_width;
auto nmargn = (nWH - scale_x*qr_width) / 2;
for (int y = 0; y < qr_width; y++)
{
for (int x = 0; x < qr_width; x++)
{
unsigned char b = mRQData[y * qr_width + x];
if (b & 0x01)
{
QRectF r(x * scale_x + nmargn, y * scale_x + nmargn, scale_x, scale_x);
painter.drawRect(r);
}
}
}
}
3.在主ui中使用输入面板,内容有变化后通过“QRWidget”展示二维码的变化。qt5qrcode.cpp代码如下:
#include "qt5qrcode.h"
#include <QDebug>
#include <QPainter>
#include <QColorDialog>
#include <QFileDialog>
Qt5QRcode::Qt5QRcode(QWidget *parent)
: QDialog(parent)
{
ui.setupUi(this);
}
Qt5QRcode::~Qt5QRcode()
{
}
void Qt5QRcode::on_tx_input_textChanged()
{
char sInput[4096] = { 0 };
auto tx = ui.tx_input->toPlainText();
if (ui.rbtn_phone->isChecked()){
tx = "tel:" + tx;
}
else if (ui.rbtn_url->isChecked()){
if (tx.indexOf("http://") != 0){
tx = "http://" + tx;
}
}
else if (ui.rbtn_sms->isChecked()){
tx = "SMSTO:" + ui.edt_telphone->text() + ":" + tx;
}
strcpy(sInput, tx.toUtf8().data());
ui.wdt_qrcode->SetData(sInput);
ui.wdt_qrcode->update();
}
void Qt5QRcode::on_btn_save_clicked()
{
auto svPath = QFileDialog::getSaveFileName(this, QString::fromLocal8Bit("保存二维码"),
QApplication::applicationDirPath()+"/qrcode.png","PNG (*.png);;BMP (*.bmp);;JPEG (*.jpg *.jpeg)");
if (svPath.isEmpty()){
return;
}
auto svPic = QPixmap::grabWidget(ui.wdt_qrcode);
svPic.save(svPath);
}
void Qt5QRcode::on_btn_color_clicked()
{
auto col = QColorDialog::getColor(ui.wdt_qrcode->GetColor());
ui.wdt_qrcode->SetColor(col);
ui.btn_color->setStyleSheet(QString("color:%1").arg(col.name()));
}
void Qt5QRcode::on_rbtn_text_clicked()
{
ui.wdt_phone->hide();
on_tx_input_textChanged();
}
void Qt5QRcode::on_rbtn_phone_clicked()
{
on_rbtn_text_clicked();
}
void Qt5QRcode::on_rbtn_url_clicked()
{
on_rbtn_text_clicked();
}
void Qt5QRcode::on_rbtn_sms_clicked()
{
ui.wdt_phone->show();
on_tx_input_textChanged();
}
界面展示如下
1.普通文本二维码
2.展示电话号码二维码
3.展示网址,扫描二维码打开对应网址
4.展示短信息的二维码
扫描快捷创建短消息,供用户发送
5.我们可以选择二维码背景颜色,以及把二维码保存成图片
6.二维码中间还可以插入logo,不过本项目并没有去实现
完整项目下载
Qt5QRcode: 前往下载.