Skip to content

Commit d4f0971

Browse files
committed
Merge #454: Add QRImageProvider
154c8e6 qml: Use QRImage in RequestPayment (goqusan) c46517b qml: Add QRImage control (goqusan) 9e1f8a0 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 154c8e6 Tree-SHA512: eb4b57245943ca34495e10de6a2bc8e28a6d1148f5aa99d7150d48c2a49e9049c2c4d3b3a481780c9e55efa07c3caed45f18bb2f8aaa1c5bdb621cadadaa82df
2 parents d42b2d3 + 154c8e6 commit d4f0971

File tree

6 files changed

+114
-6
lines changed

6 files changed

+114
-6
lines changed

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);

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>

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+
}

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
}

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+
}

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)