最近一个项目需要显示二维码,所以花了点时间(只用了一个晚上,写的很不完善),写了个显示二维码的控件。当然这个控件用到了些开源的代码,比如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 的话还遇到了点小问题,报的错误如下:

  1. ...
  2. checking for pkg-config... no
  3. checking for strdup... yes
  4. checking for pthread_mutex_init in -lpthread... yes
  5. checking for png... no
  6. configure: error: in `/home/Ivan/qrencode-3.4.4':
  7. configure: error: The pkg-config script could not be found or is too old.  Make sure it
  8. is in your PATH or set the PKG_CONFIG environment variable to the full
  9. path to pkg-config.
  10. Alternatively, you may set the environment variables png_CFLAGS
  11. and png_LIBS to avoid the need to call pkg-config.
  12. See the pkg-config man page for more details.
  13. To get pkg-config, see <http://pkg-config.freedesktop.org/>.
  14. 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 模式下使用。

我写的控件很简单,具体的看代码吧

  1. #ifndef QRWIDGET_H
  2. #define QRWIDGET_H
  3. #include <QWidget>
  4. #include "qrencode.h"
  5. class QRWidget : public QWidget
  6. {
  7. Q_OBJECT
  8. public:
  9. explicit QRWidget(QWidget *parent = 0);
  10. ~QRWidget();
  11. void setString(QString str);
  12. int getQRWidth() const;
  13. bool saveImage(QString name, int size);
  14. private:
  15. void draw(QPainter &painter, int width, int height);
  16. QString string;
  17. QRcode *qr;
  18. signals:
  19. protected:
  20. void paintEvent(QPaintEvent *);
  21. QSize sizeHint() const;
  22. QSize minimumSizeHint() const;
  23. public slots:
  24. };
  25. #endif // QRWIDGET_H
  1. #include "qrwidget.h"
  2. #include <QPainter>
  3. #include <QImage>
  4. QRWidget::QRWidget(QWidget *parent) : QWidget(parent)
  5. {
  6. qr = NULL;
  7. setString("Hello QR Code");
  8. }
  9. QRWidget::~QRWidget()
  10. {
  11. if(qr != NULL)
  12. {
  13. QRcode_free(qr);
  14. }
  15. }
  16. int QRWidget::getQRWidth() const
  17. {
  18. if(qr != NULL)
  19. {
  20. return qr->width;
  21. }
  22. else
  23. {
  24. return 0;
  25. }
  26. }
  27. void QRWidget::setString(QString str)
  28. {
  29. string = str;
  30. if(qr != NULL)
  31. {
  32. QRcode_free(qr);
  33. }
  34. qr = QRcode_encodeString(string.toStdString().c_str(),
  35. 1,
  36. QR_ECLEVEL_L,
  37. QR_MODE_8,
  38. 1);
  39. update();
  40. }
  41. QSize QRWidget::sizeHint()  const
  42. {
  43. QSize s;
  44. if(qr != NULL)
  45. {
  46. int qr_width = qr->width > 0 ? qr->width : 1;
  47. s = QSize(qr_width * 4, qr_width * 4);
  48. }
  49. else
  50. {
  51. s = QSize(50, 50);
  52. }
  53. return s;
  54. }
  55. QSize QRWidget::minimumSizeHint()  const
  56. {
  57. QSize s;
  58. if(qr != NULL)
  59. {
  60. int qr_width = qr->width > 0 ? qr->width : 1;
  61. s = QSize(qr_width, qr_width);
  62. }
  63. else
  64. {
  65. s = QSize(50, 50);
  66. }
  67. return s;
  68. }
  69. bool QRWidget::saveImage(QString fileName, int size)
  70. {
  71. if(size != 0 && !fileName.isEmpty())
  72. {
  73. QImage image(size, size, QImage::Format_Mono);
  74. QPainter painter(&image);
  75. QColor background(Qt::white);
  76. painter.setBrush(background);
  77. painter.setPen(Qt::NoPen);
  78. painter.drawRect(0, 0, size, size);
  79. if(qr != NULL)
  80. {
  81. draw(painter, size, size);
  82. }
  83. return image.save(fileName);
  84. }
  85. else
  86. {
  87. return false;
  88. }
  89. }
  90. void QRWidget::draw(QPainter &painter, int width, int height)
  91. {
  92. QColor foreground(Qt::black);
  93. painter.setBrush(foreground);
  94. const int qr_width = qr->width > 0 ? qr->width : 1;
  95. double scale_x = width / qr_width;
  96. double scale_y = height / qr_width;
  97. for( int y = 0; y < qr_width; y ++)
  98. {
  99. for(int x = 0; x < qr_width; x++)
  100. {
  101. unsigned char b = qr->data[y * qr_width + x];
  102. if(b & 0x01)
  103. {
  104. QRectF r(x * scale_x, y * scale_y, scale_x, scale_y);
  105. painter.drawRects(&r, 1);
  106. }
  107. }
  108. }
  109. }
  110. void QRWidget::paintEvent(QPaintEvent *)
  111. {
  112. QPainter painter(this);
  113. QColor background(Qt::white);
  114. painter.setBrush(background);
  115. painter.setPen(Qt::NoPen);
  116. painter.drawRect(0, 0, width(), height());
  117. if(qr != NULL)
  118. {
  119. draw(painter, width(), height());
  120. }
  121. }

下面是软件界面:

http://blog.csdn.net/liyuanbhu/article/details/44599031

我写的一个Qt 显示二维码( QR Code)的控件(可以去掉对 libpthread 的依赖,而且编译出的库文件可以在 vc2010 的release 模式下使用)的更多相关文章

  1. 二维码(QR Code)生成与解析

    二维码(QR Code)生成与解析 写在前面 经常在大街上听到扫码送什么什么,如果真闲着没事,从头扫到位,估计书包都装满了各种东西.各种扫各种送,太泛滥了.项目中从没接触过二维码的东东,最近要使用,就 ...

  2. 二维码QR Code简介及其解码实现(zxing-cpp)

    二维码QR Code(Quick Response Code)是由Denso公司于1994年9月研制的一种矩阵二维码符号,它具有一维条码及其它二维条码所具有的信息容量大.可靠性高.可表示汉字及图象多种 ...

  3. (zxing.net)二维码QR Code的简介、实现与解码

    一.简介 二维码QR Code(Quick Response Code)是由Denso公司于1994年9月研制的一种矩阵二维码符号,它具有一维条码及其它二维条码所具有的信息容量大.可靠性高.可表示汉字 ...

  4. [C#]二维码(QR Code)生成与解析

    写在前面 经常在大街上听到扫码送什么什么,如果真闲着没事,从头扫到位,估计书包都装满了各种东西.各种扫各种送,太泛滥了.项目中从没接触过二维码的东东,最近要使用,就扒了扒网络,发现关于解析二维码的类库 ...

  5. (转)QRCODE二维码介绍及常用控件推荐

    什么是QR Code码? QR Code码是由日本Denso公司于1994年9月研制的一种矩阵二维码符号,它具有一维条码及其它二维条码所具有的信息容量大.可靠性高.可表示汉字及图象多种文字信息.保密防 ...

  6. 用ABAP 生成二维码 QR Code

    除了使用我的这篇blogStep by step to create QRCode in ABAP Webdynpro提到的使用ABAP webdynpro生成二维码之外,也可以通过使用二维码在线生成 ...

  7. 动态创建div(鼠标放上显示二维码)

    最近的微信大行其道.各个网站上都给出的微信验证码,进行手机扫描加入. 怎么创建类似与点击鼠标弹出一个浮动的div显示二维码的这种效果. 1.首先制作好这样的图片,写css样式 <style ty ...

  8. mac版微信web开发者工具(小程序开发工具)无法显示二维码 解决方案

    微信小程序概念的提出,绝对可以算得上中国IT界惊天动地的一件大事,这可能意味着一场新的开发热潮即将到来, 我也怀着激动的心情准备全身心投入其中,不过截止目前,在官方网站上下载的最新版本都无法使用,打开 ...

  9. 解决Mac版微信小程序开发工具打开后无法显示二维码

    问题描述: 正常情况下,打开微信小程序开发工具后,首页提示扫描二维码进行登陆,但是如果不显示二维码,当然无法登陆. 解决方案: 无法显示二维码肯定是程序运行哪里出错了,我们直接点击桌面图标是无法排查错 ...

随机推荐

  1. Web自动化测试(全网最给力自动化教程)

    http://www.cnblogs.com/zidonghua/p/7430083.html python+selenium自动化软件测试(第2章):WebDriver API 欢迎您来阅读和练手! ...

  2. MySQL旧版本ORDER BY 方法

    MySQL 的order by 它涉及到三个参数:A. sort_buffer_size 排序缓存.B. read_rnd_buffer_size 第二次排序缓存.C. max_length_for_ ...

  3. 一个2013届毕业生(踏上IT行业)的迷茫(3)

    高中,是校园题材中出现最多的角色,但我的高中缺非常灰淡.我上的高中在我们镇上,记得在上小学的时候我哥在高中,我每次从学校门口过的时候都感觉高中好大,门口好漂亮,但是我从来都没敢进去.就在2006年我以 ...

  4. Step-By-Step Installation of RAC with RAW Datafiles on Windows 2000

     Step-By-Step Installation of RAC with RAW Datafiles on Windows 2000 Purpose This document will pr ...

  5. qLibc 对于C C++都是一个很好的框架,提供Tree Hash Stack String I/O File Time等功能

    qLibc Copyright qLibc is published under 2-clause BSD license known as Simplified BSD License. Pleas ...

  6. Asp.net C# 获取本周上周本月上月本年上年第一天最后一天时间大全

    DateTime dt = DateTime.Now; int weeknow = Convert.ToInt32(DateTime.Now.DayOfWeek); ) * weeknow + ; D ...

  7. dp_Pku1887

    <span style="color:#000099;">/* A - 单纯dp 示例 Time Limit:1000MS Memory Limit:30000KB 6 ...

  8. 机器学习: 基于MRF和CNN的图像合成

    前面我们介绍了基于卷积神经网络的图像风格迁移,利用一张content image 和 style image,可以让最终的图像既保留content image的基本结构,又能显示一定的style im ...

  9. vs2008 命令窗口 命令窗口 和 反汇编窗口的使用

    visual studio 的功能相当强大,用了一年多,也只是了解了皮毛.今天学习了一下VS2008 的 即时窗口 命令窗口 和 反汇编窗口的使用.之所以会想到要使用即时窗口是因为最近开发遇到了一个问 ...

  10. Windows系统的四个重要概念——进程、线程、虚拟内存、内核模式和用户模式

    引言 本来在写一篇Windows内存管理的文章,写着写着就发现好多基础的概念都要先讲.更可怕的是,这些基础的概念我却不能完全讲清楚.只好再把这本<深入解析Windows操作系统>翻到第一章 ...