add new example 'qsqlite': use SQL from Lisp, load QML images from DB

This commit is contained in:
pls.153 2025-03-21 12:16:34 +01:00
parent a9d93035b6
commit 121170fcbd
17 changed files with 577 additions and 0 deletions

View file

@ -0,0 +1,94 @@
#include "qt.h"
#include <QSqlQuery>
#include <QSqlError>
#include <QQuickView>
#include <QtDebug>
QObject* ini() {
static QObject* qt = nullptr;
if (qt == nullptr) {
qt = new QT;
}
return qt;
}
QT::QT() : QObject() {
}
QVariant QT::dataPath(const QVariant& prefix) {
// for desktop
QString path = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation);
path.truncate(path.lastIndexOf(QChar('/')));
path.append(QStringLiteral("/lqml-qsqlite/") + prefix.toString());
return path;
}
// SQL
QVariant QT::iniDb(const QVariant& vName, const QVariant& vQuickView) {
// add database image provider, in order to load images in QML directly from a SQL database
auto quickView = vQuickView.value<QQuickView*>();
quickView->engine()->addImageProvider(QLatin1String("db"), new DatabaseImageProvider(this));
// ini
db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(vName.toString());
return vName;
}
QVariant QT::sqlQuery(const QVariant& vQuery, const QVariant& vValues, const QVariant& vCols) {
QVariantList results;
QSqlQuery sqlQuery(db);
if (db.open()) {
QString query = vQuery.toString();
sqlQuery.prepare(vQuery.toString());
const QVariantList values = vValues.value<QVariantList>();
for (auto value : values) {
sqlQuery.addBindValue(value);
}
if (sqlQuery.exec()) {
auto cols = vCols.toInt();
while (sqlQuery.next()) {
if (cols > 1) {
QVariantList list;
for (auto r = 0; r < cols; r++) {
list << sqlQuery.value(r);
}
results << QVariant(list);
} else {
results << sqlQuery.value(0);
}
}
if (!cols && query.startsWith("insert", Qt::CaseInsensitive)) {
results << sqlQuery.lastInsertId();
}
db.close();
return results;
}
db.close();
}
QString text;
if (sqlQuery.lastError().isValid()) {
text = sqlQuery.lastError().text();
} else {
text = db.lastError().text();
}
qDebug() << "SQL error:" << text;
return QVariant();
}
// database image provider
QPixmap DatabaseImageProvider::requestPixmap(const QString& name, QSize* size, const QSize& requestedSize) {
auto result = qt->sqlQuery(
"select data from images where name = ?",
QVariantList() << name,
1); // number of returned columns
QPixmap pixmap;
pixmap.loadFromData(result.value<QVariantList>().first().toByteArray());
*size = pixmap.size();
if (requestedSize.isValid() && (pixmap.size() != requestedSize)) {
pixmap = pixmap.scaled(requestedSize);
}
return pixmap;
}

36
examples/qsqlite/cpp/qt.h Normal file
View file

@ -0,0 +1,36 @@
#pragma once
#include <QtCore>
#include <QSqlDatabase>
#include <QQuickImageProvider>
#ifdef Q_CC_MSVC
#define LIB_EXPORT __declspec(dllexport)
#else
#define LIB_EXPORT
#endif
extern "C" { LIB_EXPORT QObject* ini(); }
class QT : public QObject {
Q_OBJECT
public:
Q_INVOKABLE QVariant dataPath(const QVariant&);
Q_INVOKABLE QVariant iniDb(const QVariant&, const QVariant&);
Q_INVOKABLE QVariant sqlQuery(const QVariant&, const QVariant&, const QVariant&);
QT();
QSqlDatabase db;
};
class DatabaseImageProvider : public QQuickImageProvider {
public:
DatabaseImageProvider(QT* _qt) : QQuickImageProvider(QQuickImageProvider::Pixmap), qt(_qt) {}
QPixmap requestPixmap(const QString&, QSize*, const QSize&);
QT* qt;
};

View file

@ -0,0 +1,27 @@
QT += sql quick
TEMPLATE = lib
CONFIG += c++17 plugin release no_keywords
DEFINES += PLUGIN
INCLUDEPATH = /usr/local/include ../../../src/cpp
LIBS = -L/usr/local/lib -lecl
DESTDIR = ./
TARGET = qt
OBJECTS_DIR = ./tmp/
MOC_DIR = ./tmp/
HEADERS += qt.h
SOURCES += qt.cpp
linux {
LIBS += -L../../../platforms/linux/lib
}
macx {
LIBS += -L../../../platforms/macos/lib
}
win32 {
include(../../../src/windows.pri)
LIBS += -L../../../platforms/windows/lib
}