Browse Source

Custom qrcode renderer to allow smooth resizing

import_zecw
Aditya Kulkarni 6 years ago
parent
commit
75e755707c
  1. 33
      src/mainwindow.cpp
  2. 17
      src/mainwindow.ui
  3. 56
      src/qrcodelabel.cpp
  4. 23
      src/qrcodelabel.h
  5. 6
      zec-qt-wallet.pro

33
src/mainwindow.cpp

@ -701,38 +701,7 @@ void MainWindow::setupRecieveTab() {
}
ui->txtRecieve->setPlainText(addr);
QSize sz = ui->qrcodeDisplay->size();
QPixmap pm(sz);
pm.fill(Qt::white);
QPainter painter(&pm);
// 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(addr.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);
const double offset = (w - size) > 0 ? (w - size) / 2 : 0;
// 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(QColor(Qt::black));
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+ offset, ry1=(y+1)*scale;
QRectF r(rx1, ry1, scale, scale);
painter.drawRects(&r,1);
}
}
}
ui->qrcodeDisplay->setPixmap(pm);
ui->qrcodeDisplay->setAddress(addr);
});
}

17
src/mainwindow.ui

@ -22,7 +22,7 @@
<item row="0" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>3</number>
<number>2</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
@ -316,8 +316,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>849</width>
<height>369</height>
<width>841</width>
<height>321</height>
</rect>
</property>
<layout class="QVBoxLayout" name="sendToLayout">
@ -670,7 +670,7 @@
</widget>
</item>
<item>
<widget class="QLabel" name="qrcodeDisplay">
<widget class="QRCodeLabel" name="qrcodeDisplay">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
@ -718,7 +718,7 @@
<x>0</x>
<y>0</y>
<width>889</width>
<height>19</height>
<height>22</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
@ -783,6 +783,13 @@
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>QRCodeLabel</class>
<extends>QLabel</extends>
<header>qrcodelabel.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>tabWidget</tabstop>
<tabstop>inputsCombo</tabstop>

56
src/qrcodelabel.cpp

@ -0,0 +1,56 @@
#include "qrcodelabel.h"
QRCodeLabel::QRCodeLabel(QWidget *parent) :
QLabel(parent)
{
this->setMinimumSize(1,1);
setScaledContents(false);
}
QSize QRCodeLabel::sizeHint() const
{
int w = this->width();
return QSize(w, w); // 1:1
}
void QRCodeLabel::resizeEvent(QResizeEvent * e)
{
if(!address.isEmpty())
QLabel::setPixmap(scaledPixmap());
}
QPixmap QRCodeLabel::scaledPixmap() const {
QPixmap pm(size());
pm.fill(Qt::white);
QPainter painter(&pm);
qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(address.toUtf8().constData(), qrcodegen::QrCode::Ecc::LOW);
const int s = qr.getSize()>0?qr.getSize():1;
const double w = pm.width();
const double h = pm.height();
const double aspect = w/h;
const double size = ((aspect>1.0)?h:w);
const double scale = size/(s+2);
const double offset = (w - size) > 0 ? (w - size) / 2 : 0;
// NOTE: For performance reasons my implementation only draws the foreground parts
painter.setPen(Qt::NoPen);
painter.setBrush(QColor(Qt::black));
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+ offset, ry1=(y+1)*scale;
QRectF r(rx1, ry1, scale, scale);
painter.drawRects(&r,1);
}
}
}
return pm;
}
void QRCodeLabel::setAddress(QString addr) {
address = addr;
QLabel::setPixmap(scaledPixmap());
}

23
src/qrcodelabel.h

@ -0,0 +1,23 @@
#ifndef QRCODELABEL_H
#define QRCODELABEL_H
#include "precompiled.h"
class QRCodeLabel : public QLabel
{
Q_OBJECT
public:
explicit QRCodeLabel(QWidget *parent = 0);
virtual QSize sizeHint() const;
void setAddress(QString address);
QPixmap scaledPixmap() const;
public slots:
void resizeEvent(QResizeEvent *);
private:
QString address;
};
#endif // QRCODELABEL_H

6
zec-qt-wallet.pro

@ -51,7 +51,8 @@ SOURCES += \
src/senttxstore.cpp \
src/txtablemodel.cpp \
src/turnstile.cpp \
src/utils.cpp
src/utils.cpp \
src/qrcodelabel.cpp
HEADERS += \
src/mainwindow.h \
@ -67,7 +68,8 @@ HEADERS += \
src/txtablemodel.h \
src/senttxstore.h \
src/turnstile.h \
src/utils.h
src/utils.h \
src/qrcodelabel.h
FORMS += \
src/mainwindow.ui \

Loading…
Cancel
Save