Skip to content

Commit b411e58

Browse files
committed
Merge #454: Add QRImageProvider
f445e65 qml: Use QRImage in RequestPayment (goqusan) 53788b6 qml: Add QRImage control (goqusan) 33c0467 qml: Add QRImageProvider (goqusan) Pull request description: The `QRImageProvider` can be used to display QR codes in QML `Image`. The new control `QRImage` wraps the new provider in a convenient way. The `RequestPayment` page is updated to showcase `QRImage` usage. ACKs for top commit: johnny9: tACK f445e65 Tree-SHA512: eb4b57245943ca34495e10de6a2bc8e28a6d1148f5aa99d7150d48c2a49e9049c2c4d3b3a481780c9e55efa07c3caed45f18bb2f8aaa1c5bdb621cadadaa82df
2 parents 849d3ae + f445e65 commit b411e58

File tree

7 files changed

+117
-6
lines changed

7 files changed

+117
-6
lines changed

src/Makefile.qt.include

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ BITCOIN_QT_H = \
147147
qml/bitcoinamount.h \
148148
qml/guiconstants.h \
149149
qml/imageprovider.h \
150+
qml/qrimageprovider.h \
150151
qml/util.h \
151152
qml/walletqmlcontroller.h \
152153
qt/addressbookpage.h \
@@ -342,6 +343,7 @@ BITCOIN_QML_BASE_CPP = \
342343
qml/models/walletqmlmodel.cpp \
343344
qml/models/walletqmlmodeltransaction.cpp \
344345
qml/imageprovider.cpp \
346+
qml/qrimageprovider.cpp \
345347
qml/util.cpp \
346348
qml/walletqmlcontroller.cpp
347349

@@ -436,6 +438,7 @@ QML_RES_QML = \
436438
qml/controls/OptionButton.qml \
437439
qml/controls/OptionSwitch.qml \
438440
qml/controls/OutlineButton.qml \
441+
qml/controls/QRImage.qml \
439442
qml/controls/PageIndicator.qml \
440443
qml/controls/PageStack.qml \
441444
qml/controls/ProgressIndicator.qml \

src/qml/bitcoin.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include <qml/models/walletlistmodel.h>
3636
#include <qml/models/walletqmlmodel.h>
3737
#include <qml/models/walletqmlmodeltransaction.h>
38+
#include <qml/qrimageprovider.h>
3839
#include <qml/util.h>
3940
#include <qml/walletqmlcontroller.h>
4041
#include <qt/guiutil.h>
@@ -313,6 +314,7 @@ int QmlGuiMain(int argc, char* argv[])
313314
QScopedPointer<const NetworkStyle> network_style{NetworkStyle::instantiate(Params().GetChainType())};
314315
assert(!network_style.isNull());
315316
engine.addImageProvider(QStringLiteral("images"), new ImageProvider{network_style.data()});
317+
engine.addImageProvider(QStringLiteral("qr"), new QRImageProvider);
316318

317319
engine.rootContext()->setContextProperty("networkTrafficTower", &network_traffic_tower);
318320
engine.rootContext()->setContextProperty("nodeModel", &node_model);

src/qml/bitcoin_qml.qrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
<file>controls/PageIndicator.qml</file>
4848
<file>controls/PageStack.qml</file>
4949
<file>controls/ProgressIndicator.qml</file>
50+
<file>controls/QRImage.qml</file>
5051
<file>controls/qmldir</file>
5152
<file>controls/SendOptionsPopup.qml</file>
5253
<file>controls/Setting.qml</file>

src/qml/controls/QRImage.qml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright (c) 2025 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
import QtQuick 2.15
6+
7+
Image {
8+
id: root
9+
10+
property string code: ""
11+
property color backgroundColor: Qt.black
12+
property color foregroundColor: Qt.white
13+
14+
fillMode: Image.PreserveAspectFit
15+
smooth: false
16+
source: `image://qr/${encodeURIComponent(root.code)}?&fg=${encodeURIComponent(root.foregroundColor)}&bg=${encodeURIComponent(root.backgroundColor)}`
17+
}

src/qml/pages/wallet/RequestPayment.qml

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ Page {
199199
clearRequest.visible = true
200200
title.text = qsTr("Payment request #" + requestCounter)
201201
address.text = "bc1q f5xe y2tf 89k9 zy6k gnru wszy 5fsa truy 9te1 bu"
202+
qrImage.code = "bc1qf5xey2tf89k9zy6kgnruwszy5fsatruy9te1bu"
202203
continueButton.text = qsTr("Copy payment request")
203204
}
204205
}
@@ -220,19 +221,26 @@ Page {
220221
clearRequest.visible = false
221222
title.text = qsTr("Request a payment")
222223
address.text = ""
224+
qrImage.code = ""
223225
continueButton.text = qsTr("Create bitcoin address")
224226
}
225227
}
226228
}
227229

228-
Rectangle {
229-
id: qrPlaceholder
230+
Pane {
230231
Layout.alignment: Qt.AlignTop
231232
Layout.minimumWidth: 150
232-
Layout.maximumWidth: 150
233-
color: Theme.color.neutral2
234-
width: 150
235-
height: 150
233+
Layout.minimumHeight: 150
234+
padding: 0
235+
background: Rectangle {
236+
color: Theme.color.neutral2
237+
visible: qrImage.code === ""
238+
}
239+
contentItem: QRImage {
240+
id: qrImage
241+
backgroundColor: "transparent"
242+
foregroundColor: Theme.color.neutral9
243+
}
236244
}
237245
}
238246
}

src/qml/qrimageprovider.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright (c) 2025 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <qml/qrimageprovider.h>
6+
7+
#if defined(HAVE_CONFIG_H)
8+
#include <config/bitcoin-config.h> /* for USE_QRCODE */
9+
#endif
10+
11+
#ifdef USE_QRCODE
12+
#include <qrencode.h>
13+
#endif
14+
15+
#include <QImage>
16+
#include <QQuickImageProvider>
17+
#include <QSize>
18+
#include <QString>
19+
#include <QUrl>
20+
#include <QUrlQuery>
21+
22+
QRImageProvider::QRImageProvider()
23+
: QQuickImageProvider{QQuickImageProvider::Image}
24+
{
25+
}
26+
27+
QImage QRImageProvider::requestImage(const QString& id, QSize* size, const QSize& requested_size)
28+
{
29+
#ifdef USE_QRCODE
30+
const QUrl url{"image:///" + id};
31+
const QUrlQuery query{url};
32+
const QString data{url.path().mid(1)};
33+
const QColor fg{query.queryItemValue("fg")};
34+
const QColor bg{query.queryItemValue("bg")};
35+
36+
QRcode* code = QRcode_encodeString(data.toUtf8().constData(), 0, QR_ECLEVEL_L, QR_MODE_8, 1);
37+
38+
if (code) {
39+
QImage image{code->width, code->width, QImage::Format_ARGB32};
40+
unsigned char* p = code->data;
41+
for (int y = 0; y < code->width; ++y) {
42+
for (int x = 0; x < code->width; ++x) {
43+
image.setPixelColor(x, y, (*p & 1) ? fg : bg);
44+
++p;
45+
}
46+
}
47+
*size = QSize(code->width, code->width);
48+
QRcode_free(code);
49+
return image;
50+
}
51+
#endif // USE_QRCODE
52+
QImage pixel{1, 1, QImage::Format_ARGB32};
53+
pixel.setPixelColor(0, 0, QColorConstants::Transparent);
54+
*size = QSize(1, 1);
55+
return pixel;
56+
}

src/qml/qrimageprovider.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (c) 2025 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_QML_QRIMAGEPROVIDER_H
6+
#define BITCOIN_QML_QRIMAGEPROVIDER_H
7+
8+
#include <QQuickImageProvider>
9+
10+
QT_BEGIN_NAMESPACE
11+
class QImage;
12+
class QSize;
13+
class QString;
14+
QT_END_NAMESPACE
15+
16+
class QRImageProvider : public QQuickImageProvider
17+
{
18+
public:
19+
explicit QRImageProvider();
20+
21+
QImage requestImage(const QString& id, QSize* size, const QSize& requested_size) override;
22+
};
23+
24+
#endif // BITCOIN_QML_QRIMAGEPROVIDER_H

0 commit comments

Comments
 (0)