c++ - C++ wxWidgets显示并生成二维码
问题描述
如何在 wxWidgets 中设置和显示自定义二维码,以编码和显示字符串?
(自行回答,随时提供更好的答案)
解决方案
使用wxImagePanel示例和nayuki/QR-Code-generator C++ 库,您可以传递字符串和比例,然后 QR 码将生成并显示。
创建的文件有:
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();
};
推荐阅读
- docker - 为什么具有弹性搜索状态的 docker 映像总是重新启动?
- javascript - 如何在 UI5 中正确附加和分离事件处理程序
- matlab - 在 Matlab 的 parfor 中防止广播变量
- unity3d - 如何制作一个指向玩家要去的地方、向后向上和向下指向的摄像机?
- javascript - JavaScript/lodash:如何使用 omitBy 按值从对象中删除对象?
- listview - 从一个构建调用函数到另一个构建
- python-3.x - Python 类,运算符重载
- c# - 限制一行网格内的鼠标移动事件 - wpf c#
- java - 从 1 个项目构建多个 apk,用于在 Playstore 中上传
- java - JSP中的图片不显示