Qt生成二維碼

爲了方便,這裏使用的是nayuki寫的庫,下載之後將相應的文件include進來就可以。新建一個Qt項目,在項目目錄下新建libs目錄,然後將BitBuffer.hpp、BitBuffer.cpp、QrCode.hpp、QrCode.cpp、QrSegment.hpp和QrSegment.cpp放到libs目錄下,下面是實例
mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPainter>

#include "libs/QrCode.hpp"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow {
    Q_OBJECT

public:
    explicit MainWindow(QWidget* parent = nullptr);
    ~MainWindow();

    void paintQR(QPainter& painter, QPoint point, const QSize sz, const QString& data, QColor fg);
    QString asciiQR(const QString& data, QString on = "█", QString off = " ");

protected:
    void paintEvent(QPaintEvent*);

private:
    Ui::MainWindow* ui;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

// 必須在paintEvent()裏繪圖,所以這裏對paintEvent()進行重載
void MainWindow::paintEvent(QPaintEvent*)
{
    QPainter painter(this);

    QSize size;
    size.setWidth(300);
    size.setHeight(300);
    paintQR(painter, QPoint(30, 40), size, "Hello, Sorel", QColor(0, 0, 0)); // 黑色前景,白色背景
    painter.end();
}

void MainWindow::paintQR(QPainter& painter, QPoint point, const QSize sz, const QString& data, QColor fg)
{
    qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(data.toUtf8().constData(), qrcodegen::QrCode::Ecc::LOW);
    const int s = qr.getSize() > 0 ? qr.getSize() : 1;
    const double w = sz.width();
    const double h = sz.height();
    const double aspect = w / h;
    const double size = ((aspect > 1.0) ? h : w);
    const double scale = size / (s + 2);

    // NOTE: For performance reasons my implementation only draws the foreground parts in supplied color.
    // It expects background to be prepared already (in white or whatever is preferred).
    painter.setPen(Qt::NoPen);
    painter.setBrush(fg);
    for (int y = 0; y < s; y++) {
        for (int x = 0; x < s; x++) {
            const int color = qr.getModule(x, y); // 0 for white, 1 for black
            if (0 != color) {
                const double rx1 = (x + 1) * scale + point.x();
                const double ry1 = (y + 1) * scale + point.y();
                QRectF r(rx1, ry1, scale, scale);
                painter.drawRects(&r, 1);
            }
        }
    }
}

QString MainWindow::asciiQR(const QString& data, QString on, QString off)
{
    char* str = data.toUtf8().data();
    qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(str, qrcodegen::QrCode::Ecc::LOW);
    const int s = qr.getSize() > 0 ? qr.getSize() : 1;
    QString out = "";
    for (int y = 0; y < s; y++) {
        out = out + "\n";
        for (int x = 0; x < s; x++) {
            const int color = qr.getModule(x, y); // 0 for white, 1 for black
            out = out + (0x0 == color ? off : on);
        }
    }
    return out;
}

main.cpp

#include <QApplication>

#include "mainwindow.h"

int main(int argc, char* argv[])
{
    QApplication a(argc, argv);

    MainWindow w;
    w.show();

    return a.exec();
}

然後用Qt Designer生成一個mainwindow.ui就可以,效果如下
在這裏插入圖片描述

參考

How to draw a QR code with Qt in native C/C++

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章