Qt-qrencode开发-生成、显示二维码📀

Qt-qrencode开发-生成二维码📀

目录

1、概述📸

qrencode是一个用于生成QR码(二维码)的库,它支持多种编程语言的接口,包括C、C++、Python等。QR码是一种矩阵式二维码,常用于存储网址、联系信息、文字信息等,广泛应用于各种场景,如产品追踪、广告宣传、文档管理等。

qrencode的设计简洁高效,提供了易于使用的API接口,使得开发者能够轻松地在应用程序中集成QR码生成和处理功能

库的基本特性

  1. 生成能力qrencode库能够生成不同版本和纠错级别的QR码,支持从最小的版本1(21x21的模块)到最高的版本40(177x177的模块),并且可以根据需要调整纠错等级(L、M、Q、H)。
  2. 输出格式:库支持生成多种格式的输出,包括PNG图片、SVG矢量图、ASCII文本形式的二维码等,这取决于库的具体实现和使用的接口。
  3. 编码内容:支持多种数据类型编码,如数字、字母、二进制数据、UTF-8文本、电子邮件地址、电话号码、URL等。
  4. C++接口 :对于C++,qrencode提供了丰富的类和方法来方便地生成二维码。用户可以创建一个QRcode对象,向其中添加数据,然后将其渲染成所需的格式。
  5. C接口 :对于C语言使用者,qrencode也提供了函数接口,通过这些函数可以直接操作二维码数据结构,进行编码和输出。
  6. 跨平台qrencode库是跨平台的,可以在多种操作系统上编译和使用,包括Windows、Linux、macOS等。
  7. 依赖 :在某些情况下,如生成PNG图片输出时,qrencode可能需要额外的依赖,如libpngzlib库。

开发环境说明

  • 系统:Windows11、Ubuntu20.04
  • Qt版本:V5.14.2
  • 编译器:MSVC2017-64、GCC/G++64
  • qrencode版本:4.1.1

2、实现效果💽

  1. 将qrencode使用Qt封装为一个生成、显示二维码的控件;
  2. 支持使用QPainter绘制显示二维码;
  3. 可通过函数接口返回生成的二维码QImage;
  4. 可通过调用函数将生成的二维码保存到指定路径;
  5. 支持使用源码嵌入工程(更好的跨平台、支持各种编译器);
  6. 支持使用编译好的静态库(MSVC2017-64);

3、编译qrencode🔍

  1. 下载源代码

  2. 将qrencode-4.1.1解压后,创建一个build文件夹;

  3. 打开Cmake,将qrencode-4.1.1文件夹下的CMakeLists.txt文件拖入CMake中;

  4. 点击【Configure】;

  5. 这里我选择了MSVC2017-64编译器,点击【Finish】;

  6. 如下图所示进行配置,配置不正确会由于没有准备依赖而报错;

    1. 设置编译后的安装路径为C:/Users/MHF/Downloads/qrencode-4.1.1/QRencode
    2. 勾选WITHOUT_PNG,表示不支持png;
    3. 取消勾选WITH_TOOLS,否则会报错。
  7. 然后点击【Generate】、【Open Project】打开VS;

  8. 鼠标右键选择【ALL_BUILD】,点击【生成】,然后选择【INSTALL】,点击【生成】;

  9. 就可以在安装路径下生成编译好的文件了;

4、在QT中引入编译为静态库的QRencode

  • 创建一个工程,将编译后的QRencode文件夹复制到工程中;

  • 在工程的pro文件中添加下列代码;

    cpp 复制代码
    CONFIG(debug, debug|release): {
    LIBS += -L$$PWD/QRencode/lib/ -lqrencoded
    }else{
    LIBS += -L$$PWD/QRencode/lib/ -lqrencode
    }
    INCLUDEPATH += $$PWD/QRencode/include
    DEPENDPATH += $$PWD/QRencode/include

5、在Qt中直接使用QRencode源码

  • 将qrencode-4.1.1文件夹中除了.h、.c、config.h.in外的文件删除,文件夹也删除,qrenc.c也删除;

  • config.h.in重命名为config.h

  • 在pro文件中添加所有.h 、.c文件

  • 注意:还需要添加DEFINES += HAVE_CONFIG_H

    cpp 复制代码
    DEFINES += HAVE_CONFIG_H
    SOURCES += \
        main.cpp \
        qrencode/bitstream.c \
        qrencode/mask.c \
        qrencode/mmask.c \
        qrencode/mqrspec.c \
        qrencode/qrencode.c \
        qrencode/qrinput.c \
        qrencode/qrspec.c \
        qrencode/rsecc.c \
        qrencode/split.c \
        widget.cpp
    
    HEADERS += \
        qrencode/bitstream.h \
        qrencode/config.h \
        qrencode/mask.h \
        qrencode/mmask.h \
        qrencode/mqrspec.h \
        qrencode/qrencode.h \
        qrencode/qrencode_inner.h \
        qrencode/qrinput.h \
        qrencode/qrspec.h \
        qrencode/rsecc.h \
        qrencode/split.h \
        widget.h
  • 编译后会报错error: C2065: "MAJOR_VERSION": 未声明的标识符

  • 打开config.h文件,如下图所示;

  • MAJOR_VERSIONMICRO_VERSIONMINOR_VERSIONVERSION四项修改为如下所示,与自己下载的版本号相同;

  • 然后就可以正常编译了;

6、在Qt中使用QRencode生成二维码示例

  • 在ui文件中添加下列控件,并将QWidget提升为QrCodeView

  • 实现代码

    cpp 复制代码
    #include "qrcodeview.h"
    #include "qrencode.h"
    #include <QDebug>
    #include <QDir>
    #include <QFileInfo>
    #include <QPainter>
    
    QrCodeView::QrCodeView(QWidget* parent)
        : QWidget{parent}
    {}
    
    void QrCodeView::setString(const QString& str)
    {
        if (str.isEmpty())
            return;
        if (m_str == str)
            return;
        m_str = str;
    
        QRcode* qrcode = QRcode_encodeString(str.toStdString().data(), 2, QR_ECLEVEL_Q, QR_MODE_8, 1);
        if (!qrcode)   // 错误返回null
        {
            qInfo() << errno;   // 打印错误码
            return;
        }
    
        int w = qMin(this->width(), this->height());   // 控件长宽的最小值,保证绘制完整正方形
        int qrcodeW = qMax(qrcode->width, 1);
        qreal size = w / qreal(qrcodeW);   // 二维码小格子的长宽
    
        m_img = QImage(w, w, QImage::Format_ARGB32);
        QPainter painter(&m_img);
        painter.setBrush(Qt::white);   // 设置白色笔刷
        painter.setPen(Qt::NoPen);
        painter.drawRect(0, 0, w, w);   // 绘制w x w的白色背景
        painter.setBrush(Qt::black);    // 设置黑色笔刷用于绘制方块
    
        for (qint32 y = 0; y < qrcodeW; y++)
        {
            for (qint32 x = 0; x < qrcodeW; x++)
            {
                unsigned char b = qrcode->data[(y * qrcodeW) + x];
                if (b & 0x01)   // 1=黑、0=白
                {
                    QRectF rect(x * size, y * size, size, size);
                    painter.drawRect(rect);   // 绘制黑色格子
                }
            }
        }
        delete qrcode;
        qrcode = nullptr;
    
        this->update();   // 绘制图片
    }
    
    /**
     * @brief       保存生成的二维码图片到指定路径
     * @param path  保存路径 + 名称.jpg
     * @return   true 保存成功
     */
    bool QrCodeView::save(const QString& path)
    {
        if (path.isEmpty() || m_img.isNull())
            return false;
    
        QFileInfo info(path);
        if (info.suffix() == "jpg" || info.suffix() == "JPG")   // 只支持保存为jpg格式
        {
            QDir().mkpath(info.path());   // 创建路径,防止路径不存在
            return m_img.save(path);
        }
        else
        {
            return false;
        }
    }
    
    /**
     * @brief   返回生成的二维码图片
     * @return
     */
    QImage QrCodeView::getImage()
    {
        return m_img;
    }
    
    /**
     * @brief          在控件中显示二维码
     * @param event
     */
    void QrCodeView::paintEvent(QPaintEvent* event)
    {
        QWidget::paintEvent(event);
    
        QPainter painter(this);
        int x = (this->width() - m_img.width()) / 2;
        int y = (this->height() - m_img.height()) / 2;
        painter.drawImage(x, y, m_img);
    }

7、完整源代码📑

🎈🎈  ☁️

🎈🎈🎈

☁️     🎈🎈🎈🎈

🎈🎈🎈🎈

☁️    ⁣🎈🎈🎈

|/

🏠   ☁️

☁️         ☁️

🌳🌻🏫🌳🏘🏢_🏘🏢🌲🌳

相关推荐
锦亦之22337 小时前
QT+OSG+OSG-earth如何在窗口显示一个地球
开发语言·qt
柳鲲鹏10 小时前
编译成功!QT/6.7.2/Creator编译Windows64 MySQL驱动(MinGW版)
开发语言·qt·mysql
三玖诶10 小时前
如何在 Qt 的 QListWidget 中逐行添加和显示数据
开发语言·qt
阳光开朗_大男孩儿16 小时前
DBUS属性原理
linux·服务器·前端·数据库·qt
Alphapeople17 小时前
Qt Modbus
开发语言·qt
竹林海中敲代码17 小时前
Qt Creator 集成开发环境 常见问题
qt·qt工具常见问题
竹林海中敲代码21 小时前
Qt安卓开发连接手机调试(红米K60为例)
android·qt·智能手机
长沙红胖子Qt1 天前
关于 Qt运行加载内存较大崩溃添加扩大运行内存 的解决方法
开发语言·qt·qt扩大运行内存
gopher95111 天前
qt相关面试题
开发语言·qt·面试
三玖诶1 天前
在 Qt 中使用 QLabel 设置 GIF 动态背景
开发语言·qt·命令模式