我寫的一個Qt 顯示二維碼( QR Code)的控制項,qtqr

來源:互聯網
上載者:User

我寫的一個Qt 顯示二維碼( QR Code)的控制項,qtqr

最近一個項目需要顯示二維碼,所以花了點時間(只用了一個晚上,寫的很不完善),寫了個顯示二維碼的控制項。當然這個控制項用到了些開源的代碼,比如qrencode,所以我也打算把My Code開源。

My Code參考了

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... nochecking for strdup... yeschecking for pthread_mutex_init in -lpthread... yeschecking for png... noconfigure: error: in `/home/Ivan/qrencode-3.4.4':configure: error: The pkg-config script could not be found or is too old.  Make sure itis in your PATH or set the PKG_CONFIG environment variable to the fullpath to pkg-config.Alternatively, you may set the environment variables png_CFLAGSand 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_OBJECTpublic:    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());    }}

下面是軟體介面:


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.