Вопрос по render, qr-code, c++, qt – Как нарисовать QR-код с Qt на родном C / C ++

23

QR в Qt

В качестве сопутствующего вопросаКак сканировать QR-коды с помощью QtЯ хочу знать, как нарисоватьQR код из собственного кода C / C ++ в моем настольном приложении на базе Qt5, но я не смог найти пример того, как это сделать.

я знаюQtQR существует, но имеет зависимости отпитон-qrtools что, на мой взгляд, в некоторой степени побеждает цель использования Qt. Я хочу гибкое, эффективное и независимое решение, которое будет компилироваться с моим приложением, где бы я ни решил его использовать.

Как я могу это сделать?

Ваш Ответ

2   ответа
30

ОБНОВЛЕНИЕ 3 / 3-2016: До меня дошло, что есть небольшой библиотечный проект, который делает то, что делает мой ответ, но в более "расфасованный» путь. Вы можете проверить этоВот.

QR в Qt

Есть небольшая библиотека генератора QR-кода на чистом C и без зависимостей, называемаяlibqrencode.

Шаг 1: Установите

Прежде чем вы сможете использовать его, вам придется установить его. На моей Ubuntu 13.10 это означало набрать следующее в оболочке:

sudo aptitude install libqrencode-dev

На других платформах вам, возможно, придется собрать его из исходного кода самостоятельно. Просто скачайте tarball и следуйте инструкциямскачать исходный код

Шаг 2: Файл проекта

Далее вам нужно будет добавить библиотеку в ваш проект. В моем файле проекта Qt5.2.0 (myproject.pro или аналогичный) это означало добавление следующей строки:

LIBS += -lqrencode

Это должно быть похоже на большинство версий Qt, которые я знаю.

Шаг 3: кодировать

Далее необходимо написать код, который на самом деле использует библиотеку для кодирования некоторой входной строки в формат QR. Это одна строка кода:

QRcode *qr=QRcode_encodeString("my string", 1, QR_ECLEVEL_L, QR_MODE_8,0);

НОТА: После экспериментов с параметрами, которые я передал этой функции, я понял, что нужно быть осторожным. Некоторые комбинации параметров потерпели неудачу без уважительной причины. Например, передача 0 в качестве версии или использование QR_MODE_AN не удалось с "Неверные параметры ", Это могут быть ошибки в древней версии библиотеки, которую я использую. Вы были предупреждены.

Шаг 4: сделать изображение

Наконец, перед очисткой необходимо преобразовать вывод в растровое изображение, чтобы его можно было отобразить на экране. Это проще, чем кажется. Вместо того, чтобы перечислять кучу предположений, я включу здесь свою полную рабочую минималистичную реализацию QRWidget. Интересные биты находятся в переопределенном методе paintEvent ().

QRWidget.hpp

#ifndef QRWIDGET_HPP
#define QRWIDGET_HPP

#include 

class QRWidget : public QWidget{
    Q_OBJECT
private:
    QString data;
public:
    explicit QRWidget(QWidget *parent = 0);
    void setQRData(QString data);

protected:
    void paintEvent(QPaintEvent *);
};

#endif // QRWIDGET_HPP

QRWidget.cpp

#include "QRWidget.hpp"
#include 
#include     
#include 

QRWidget::QRWidget(QWidget *parent) :
    QWidget(parent),
    data("Hello QR")//Note: The encoding fails with empty string so I just default to something else. Use the setQRData() call to change this.
{
}

void QRWidget::setQRData(QString data){
    this->data=data;
    update();
}

void QRWidget::paintEvent(QPaintEvent *pe){
    QPainter painter(this);
    //NOTE: I have hardcoded some parameters here that would make more sense as variables.
    QRcode *qr = QRcode_encodeString(data.toStdString().c_str(), 1, QR_ECLEVEL_L, QR_MODE_8, 0);
    if(0!=qr){
        QColor fg("black");
        QColor bg("white");
        painter.setBrush(bg);
        painter.setPen(Qt::NoPen);
        painter.drawRect(0,0,width(),height());
        painter.setBrush(fg);
        const int s=qr->width>0?qr->width:1;
        const double w=width();
        const double h=height();
        const double aspect=w/h;
        const double scale=((aspect>1.0)?h:w)/s;
        for(int y=0;y
Ты прав. Я думал о том, чтобы сделать это таким образом, но мне хотелось максимально упростить свой ответ (он был немного большим). Я мог бы обновить это позже! Lennart Rolland
Будьте осторожны: эта библиотека LGPL, которая слишком ограничена для многих целей, таких как использование в приложении для iOS. Glenn Maynard
лучше реализовать функциюpaintQrCode(QPainter &painter, const QRect &area, const QByteArray &data), Затем эту функцию можно использовать для рисования наQWidget или жеQImage или жеQGraphicsWidget избегая дублирования кода. Marek R
Вы, вероятно, хотитеQRcode *qr = QRcode_encodeString(data.toStdString().c_str(), 1, QR_ECLEVEL_L, QR_MODE_8, 0);  бытьQRcode *qr = QRcode_encodeString(data.toStdString().c_str(), 1, QR_ECLEVEL_L, QR_MODE_8, 1); иметь QR-коды без учета регистра ty812
8

Если вы чувствуете, что ФукучиБиблиотека слишком велика[0] для вас, подумайте, глядя на Наюкиs C ++ Библиотека QR-кода генератора[1]:https://github.com/nayuki/QR-Code-generator/tree/master/cpp

Nayuki»Библиотека s требует C ++ 11 и является переносимой, не требуя автоинструментов. Пример использования:

#include 
#include 
#include "QrCode.hpp"
using namespace qrcodegen;

// Create the QR Code object
QrCode qr = QrCode::encodeText("Hello, world!", QrCode::Ecc::MEDIUM);

// Read the black & white pixels
for (int y = 0; y < qr.size; y++) {
    for (int x = 0; x < qr.size; x++) {
        int color = qr.getModule(x, y);  // 0 for white, 1 for black

        // You need to modify this part
        draw_pixel_onto_QT(x, y, color);
    }
}

[0]: Fukuchi: 20 файлов, ~ 7200 строк среди основных файлов .c и .h (исключая код сборки и тестирования).

[1]: Наюки: 6 файлов, ~ 1400 строк среди основных файлов .cpp и .hpp (исключая демонстрационный код).

РЕДАКТИРОВАТЬ 2016-12-08 по OP Я решил с разрешения добавить свою собственную адаптацию в Qt. Этот код компилируется и прекрасно работает в моей системе, и я думаю, что он должен быть достаточно независимым, чтобы работать в другом месте без особых настроек.

#include "QrCode.hpp"

void paintQR(QPainter &painter, const QSize sz, const QString &data, QColor fg)
{
    // NOTE: At this point you will use the API to get the encoding and format you want, instead of my hardcoded stuff:
    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
@ Наюки, спасибо за помощь! Я сделал новое сообщение здесь:stackoverflow.com/questions/42979325/... Xsmael
Привет! Я интегрировал ваш QR-код в свой проект, и если вы хотите, чтобы я мог отредактировать ваш ответ с помощью специального кода Qt, который я сделал, таким образом он будет лучше соответствовать моему вопросу? Lennart Rolland
Я пытался использовать вашу библиотеку, и я получаю чертеж QrCode, но когда я сканирую его, он не распознается, сканер не 'ничего не понимаю ... Xsmael
Сугой не! doumo», Вы'Добро пожаловать! Nayuki

Похожие вопросы