我写的一个Qt 显示二维码( QR Code)的控件(可以去掉对 libpthread 的依赖,而且编译出的库文件可以在 vc2010 的release 模式下使用)
最近一个项目需要显示二维码,所以花了点时间(只用了一个晚上,写的很不完善),写了个显示二维码的控件。当然这个控件用到了些开源的代码,比如qrencode,所以我也打算把我的代码开源。
我的代码参考了
http://stackoverflow.com/questions/21400254/how-to-draw-a-qr-code-with-qt-in-native-c-c
基本就是按照这里面的思路来写的。
首先要下载 libqrencode,这是一个c 语言的QR code 生成库。QR Code 可以容纳 7000 个数字或者4000个字符,可以承载的信息量很大,用起来也很方便。关于QR Code更详细的信息可以自行 google.
Libqrencode 暂时只支持 QR Code model 2,如果需要ECI 或者FNC1模式的话,还要想别的办法。
编译Libqrencode 我用的是 MSYS2,直接 configure 的话还遇到了点小问题,报的错误如下:
- ...
- checking for pkg-config... no
- checking for strdup... yes
- checking for pthread_mutex_init in -lpthread... yes
- checking for png... no
- configure: error: in `/home/Ivan/qrencode-3.4.4':
- configure: error: The pkg-config script could not be found or is too old. Make sure it
- is in your PATH or set the PKG_CONFIG environment variable to the full
- path to pkg-config.
- Alternatively, you may set the environment variables png_CFLAGS
- and png_LIBS to avoid the need to call pkg-config.
- See the pkg-config man page for more details.
- To get pkg-config, see <http://pkg-config.freedesktop.org/>.
- See `config.log' for more details
大体的意思就是我的编译环境中没有 pkg-config,不过没关系,按照作者的说法,Libqrencode 不依赖于任何第三方的库。在configure 时加一个参数--without-tools ,就可以顺利通过了。
编译之后在 .lib 目录中生成一个 libqrencode.a ,再加上 qrencode.h 这两个文件就够了。我用的Qt 开发环境是 VS2010+Qt4.5.1 。Libqrencode.a 在 VS2010 中也是可以用的,另外还需要libwinpthread.dll.a 这个文件,因为Libqrencode中用到了libpthread 的一些函数。
补充一下,经过测试,这里生成的 libqrencode.a 在 VS2010 中使用还是有些问题的,表现为 Debug 模式下运行正常,可是一旦将程序编译为 Release 模式就无法运行。看来还需要用 vs2010 编译libqrencode。估计不那么简单,等有时间了折腾一下。
将 config.h 文件中
/* Define to 1 if using pthread is enabled. */
#define HAVE_LIBPTHREAD 1
改为:
//#define HAVE_LIBPTHREAD 1
就可以去掉对 libpthread 的依赖,而且编译出的库文件可以在 vc2010 的release 模式下使用。
我写的控件很简单,具体的看代码吧
- #ifndef QRWIDGET_H
- #define QRWIDGET_H
- #include <QWidget>
- #include "qrencode.h"
- class QRWidget : public QWidget
- {
- Q_OBJECT
- public:
- explicit QRWidget(QWidget *parent = 0);
- ~QRWidget();
- void setString(QString str);
- int getQRWidth() const;
- bool saveImage(QString name, int size);
- private:
- void draw(QPainter &painter, int width, int height);
- QString string;
- QRcode *qr;
- signals:
- protected:
- void paintEvent(QPaintEvent *);
- QSize sizeHint() const;
- QSize minimumSizeHint() const;
- public slots:
- };
- #endif // QRWIDGET_H
- #include "qrwidget.h"
- #include <QPainter>
- #include <QImage>
- QRWidget::QRWidget(QWidget *parent) : QWidget(parent)
- {
- qr = NULL;
- setString("Hello QR Code");
- }
- QRWidget::~QRWidget()
- {
- if(qr != NULL)
- {
- QRcode_free(qr);
- }
- }
- int QRWidget::getQRWidth() const
- {
- if(qr != NULL)
- {
- return qr->width;
- }
- else
- {
- return 0;
- }
- }
- void QRWidget::setString(QString str)
- {
- string = str;
- if(qr != NULL)
- {
- QRcode_free(qr);
- }
- qr = QRcode_encodeString(string.toStdString().c_str(),
- 1,
- QR_ECLEVEL_L,
- QR_MODE_8,
- 1);
- update();
- }
- QSize QRWidget::sizeHint() const
- {
- QSize s;
- if(qr != NULL)
- {
- int qr_width = qr->width > 0 ? qr->width : 1;
- s = QSize(qr_width * 4, qr_width * 4);
- }
- else
- {
- s = QSize(50, 50);
- }
- return s;
- }
- QSize QRWidget::minimumSizeHint() const
- {
- QSize s;
- if(qr != NULL)
- {
- int qr_width = qr->width > 0 ? qr->width : 1;
- s = QSize(qr_width, qr_width);
- }
- else
- {
- s = QSize(50, 50);
- }
- return s;
- }
- bool QRWidget::saveImage(QString fileName, int size)
- {
- if(size != 0 && !fileName.isEmpty())
- {
- QImage image(size, size, QImage::Format_Mono);
- QPainter painter(&image);
- QColor background(Qt::white);
- painter.setBrush(background);
- painter.setPen(Qt::NoPen);
- painter.drawRect(0, 0, size, size);
- if(qr != NULL)
- {
- draw(painter, size, size);
- }
- return image.save(fileName);
- }
- else
- {
- return false;
- }
- }
- void QRWidget::draw(QPainter &painter, int width, int height)
- {
- QColor foreground(Qt::black);
- painter.setBrush(foreground);
- const int qr_width = qr->width > 0 ? qr->width : 1;
- double scale_x = width / qr_width;
- double scale_y = height / qr_width;
- for( int y = 0; y < qr_width; y ++)
- {
- for(int x = 0; x < qr_width; x++)
- {
- unsigned char b = qr->data[y * qr_width + x];
- if(b & 0x01)
- {
- QRectF r(x * scale_x, y * scale_y, scale_x, scale_y);
- painter.drawRects(&r, 1);
- }
- }
- }
- }
- void QRWidget::paintEvent(QPaintEvent *)
- {
- QPainter painter(this);
- QColor background(Qt::white);
- painter.setBrush(background);
- painter.setPen(Qt::NoPen);
- painter.drawRect(0, 0, width(), height());
- if(qr != NULL)
- {
- draw(painter, width(), height());
- }
- }
下面是软件界面:
http://blog.csdn.net/liyuanbhu/article/details/44599031
我写的一个Qt 显示二维码( QR Code)的控件(可以去掉对 libpthread 的依赖,而且编译出的库文件可以在 vc2010 的release 模式下使用)的更多相关文章
- 二维码(QR Code)生成与解析
二维码(QR Code)生成与解析 写在前面 经常在大街上听到扫码送什么什么,如果真闲着没事,从头扫到位,估计书包都装满了各种东西.各种扫各种送,太泛滥了.项目中从没接触过二维码的东东,最近要使用,就 ...
- 二维码QR Code简介及其解码实现(zxing-cpp)
二维码QR Code(Quick Response Code)是由Denso公司于1994年9月研制的一种矩阵二维码符号,它具有一维条码及其它二维条码所具有的信息容量大.可靠性高.可表示汉字及图象多种 ...
- (zxing.net)二维码QR Code的简介、实现与解码
一.简介 二维码QR Code(Quick Response Code)是由Denso公司于1994年9月研制的一种矩阵二维码符号,它具有一维条码及其它二维条码所具有的信息容量大.可靠性高.可表示汉字 ...
- [C#]二维码(QR Code)生成与解析
写在前面 经常在大街上听到扫码送什么什么,如果真闲着没事,从头扫到位,估计书包都装满了各种东西.各种扫各种送,太泛滥了.项目中从没接触过二维码的东东,最近要使用,就扒了扒网络,发现关于解析二维码的类库 ...
- (转)QRCODE二维码介绍及常用控件推荐
什么是QR Code码? QR Code码是由日本Denso公司于1994年9月研制的一种矩阵二维码符号,它具有一维条码及其它二维条码所具有的信息容量大.可靠性高.可表示汉字及图象多种文字信息.保密防 ...
- 用ABAP 生成二维码 QR Code
除了使用我的这篇blogStep by step to create QRCode in ABAP Webdynpro提到的使用ABAP webdynpro生成二维码之外,也可以通过使用二维码在线生成 ...
- 动态创建div(鼠标放上显示二维码)
最近的微信大行其道.各个网站上都给出的微信验证码,进行手机扫描加入. 怎么创建类似与点击鼠标弹出一个浮动的div显示二维码的这种效果. 1.首先制作好这样的图片,写css样式 <style ty ...
- mac版微信web开发者工具(小程序开发工具)无法显示二维码 解决方案
微信小程序概念的提出,绝对可以算得上中国IT界惊天动地的一件大事,这可能意味着一场新的开发热潮即将到来, 我也怀着激动的心情准备全身心投入其中,不过截止目前,在官方网站上下载的最新版本都无法使用,打开 ...
- 解决Mac版微信小程序开发工具打开后无法显示二维码
问题描述: 正常情况下,打开微信小程序开发工具后,首页提示扫描二维码进行登陆,但是如果不显示二维码,当然无法登陆. 解决方案: 无法显示二维码肯定是程序运行哪里出错了,我们直接点击桌面图标是无法排查错 ...
随机推荐
- prettytensor 的使用
prettytensor 顾名思义,对原始的 tensorflow 下的 tensor 进行封装(prettytensor 以 tensorflow 为基础,二者搭配使用),使其成为一个更为接口友好的 ...
- 学习OpenCV研究报告指出系列(二)源代码被编译并配有实例project
下载并安装CMake3.0.1 要自己编译OpenCV2.4.9的源代码.首先.必须下载编译工具,使用的比較多的编译工具是CMake. 以下摘录一段关于CMake的介绍: CMake是一个 ...
- sparksql jdbc数据源
用的本地模式,pom.xml中添加了mysql驱动包,mysql已经开启,写入的时候发现用format("jdbc").save()的方式发现会有does not allow cr ...
- iOS CALayer使用
CALayer使用 iOS的设备中,我们之所以能看到各种各样的控件.文字.图片,都是Core Animation框架的功劳.它通过图层的合成,最终显示在屏幕上.而今天这篇文章讲的就是Core Anim ...
- TensorFlow 实战(一)—— 交叉熵(cross entropy)的定义
对多分类问题(multi-class),通常使用 cross-entropy 作为 loss function.cross entropy 最早是信息论(information theory)中的概念 ...
- Java native代码编译步骤简书
Java native代码编译步骤简书 目的:防止java代码反编译获取密码算法 (1)编写实现类com.godlet.PasswordAuth.java (2)编译java代码javac Passw ...
- 编程算法 - 二叉搜索树(binary search tree) 代码(C)
二叉搜索树(binary search tree) 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 二叉搜索树(binary search tree)能 ...
- Android 4.0开发之GridLayOut布局实践
在上一篇教程中http://blog.csdn.net/dawanganban/article/details/9952379,我们初步学习了解了GridLayout的布局基本知识,通过学习知道,Gr ...
- centos7 Intellij Idea 授权服务器搭建(Jetbrain 家族系列IDE)
centos7 Intellij Idea 授权服务器搭建 1.上传破解文件 我用的是Xshell客户端,有上传功能,但是linux必须先装lrzsz,也可以通过其他方式传到linux上 yum -y ...
- Power management in semiconductor memory system
A method for operating a memory module device. The method can include transferring a chip select, co ...