C++ wxWidgets显示并生成二维码

时间:2021-01-23 12:18:00

标签: c++ wxwidgets qr-code

如何在 wxWidgets 中设置和显示自定义二维码,以编码和显示字符串?

(自己回答,随时贡献更好的答案)

1 个答案:

答案 0 :(得分:0)

使用 wxImagePanel 示例和 nayuki/QR-Code-generator C++ 库,您可以传递字符串和比例,二维码将生成并显示。

创建的文件是:

wxImagePanel.hpp
wxImagePanel.cpp
wxQRCode.hpp
wxQRCode.cpp

首先是我的 wxImagePanel,一个小部件,它可以让您在矩形表面上设置和显示图像:

// wxImagePanel.hpp

#include <wx/wx.h>

class wxImagePanel : public wxPanel {
    private:
        wxBitmap image;
        void updateSize();

    public:
        wxImagePanel(wxFrame *parent, wxBitmap bitmap);
        wxImagePanel(wxFrame *parent);
        void paintNow();
        void paintEvent(wxPaintEvent &evt);
        void render(wxDC &dc);
        void setBitmap(wxBitmap bitmap);

        DECLARE_EVENT_TABLE()
};
// wxImagePanel.cpp

#include "wxImagePanel.hpp"

BEGIN_EVENT_TABLE(wxImagePanel, wxPanel)
EVT_PAINT(wxImagePanel::paintEvent)
END_EVENT_TABLE()

wxImagePanel::wxImagePanel(wxFrame *parent, wxBitmap bitmap): wxPanel(parent), image(bitmap) 
{
    updateSize();
};

wxImagePanel::wxImagePanel(wxFrame *parent): wxPanel(parent) {};

void wxImagePanel::updateSize() 
{
    SetMinSize(wxSize(image.GetWidth(), image.GetHeight()));
}

void wxImagePanel::paintEvent(wxPaintEvent &evt)
{
    wxPaintDC dc(this);
    render(dc);
}

void wxImagePanel::render(wxDC &dc) {
    int x = (GetSize().GetWidth() - image.GetWidth()) / 2;
    int y = (GetSize().GetHeight() - image.GetHeight()) / 2;
    dc.DrawBitmap(image, x, y, false);
}

void wxImagePanel::paintNow() {
    wxClientDC dc(this);
    render(dc);
}

void wxImagePanel::setBitmap(wxBitmap bitmap) {
    image = bitmap;
    updateSize();
    paintNow();
}

然后是一个 QR Code 类,它子类化 wxImagePanel 并显示代码:

// wxQRCode.hpp

#include "wxImagePanel.hpp"
#include <string>

class wxQRCode : public wxImagePanel 
{
    public:
        wxQRCode(wxFrame *parent, std::string text, unsigned int scale);
        void setText(std::string text);
        void setScale(int scale);
        int getQRSize();

    private:
        void generateQRBitmap();
        std::string qrText;
        unsigned int bitmapScale;
};
// wxQRCode.cpp

#include "wxQRCode.hpp"
#include "QrCode.hpp" // qr code lib
using namespace qrcodegen;

wxQRCode::wxQRCode(wxFrame *parent, std::string text, unsigned int scale)
    : wxImagePanel(parent), qrText(text), bitmapScale(scale)
{
    generateQRBitmap();
};

int wxQRCode::getQRSize()
{
    QrCode qr = QrCode::encodeText(qrText.c_str(), QrCode::Ecc::LOW);
    return qr.getSize();
}

void wxQRCode::generateQRBitmap() 
{
    QrCode qr = QrCode::encodeText(qrText.c_str(), QrCode::Ecc::LOW);
    const int scale = bitmapScale;
    const int size = qr.getSize() * scale;
    const int byteWidth = (size + 7) / 8;
    char bitsChar[size*byteWidth];

    for (int y=0; y<size; y++) {
        for (int xByte=0; xByte<byteWidth; xByte++) {
            char bitChar = 0x00;
            if (qrText != "") { for (int xBit=0; xBit<8; xBit++) {
                    int x = xByte*8 + xBit;
                    int xModule = x / scale;
                    int yModule = y / scale;
                    bool black = qr.getModule(xModule, yModule);
                    bitChar += black << (xBit % 8);
                }}
            bitsChar[y * byteWidth + xByte] = bitChar;
        }
    }
    
    wxBitmap *bitmap = new wxBitmap(bitsChar, size, size, 1);
    setBitmap(*bitmap);
};

void wxQRCode::setText(std::string text) {
    qrText = text;
    if (text != "") {
        Show(true);
        generateQRBitmap();
        paintNow();
    } else {
        Show(false);
    }
};

void wxQRCode::setScale(int scale) {
    bitmapScale = scale;
    generateQRBitmap();
    paintNow();
};
相关问题