您的位置:首页 > 编程语言 > Qt开发

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

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

[plain] view plain copy







...

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 模式下使用。

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

[cpp] view plain copy







#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

[cpp] view plain copy







#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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐