使用libqrencode生成二维码,支持telphone,短信,url等

很幸运您搜索到本文章,希望对您有帮助

今天突然想了解下二维码的算法和原理,并且做一个用第三方开源库生成二维码的工具,了解一下第三方库的调用接口。

环境搭建

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: 前往下载.

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值