QT SqlQueryModel TableView to ListView [duplicate] - qt

I want to get the model from my SQlite Database, when I set the query in the QSqlQueryModel I can get the number of rows, number of columns, etc. But the data inside each column I have a ReferenceError trying to get the name of the column
The cpp code:
//data base users
QSqlQueryModel *sqlModel = new QSqlQueryModel();
sqlModel->setQuery("SELECT usuarios.nombre FROM usuarios");
sqlModel->setHeaderData(0,Qt::Horizontal, QObject::tr("nombre"));
qDebug() << "ROL: " << sqlModel->roleNames();
qDebug() << "number of rows: " << sqlModel->rowCount();
qDebug() << "number of columns: " << sqlModel->columnCount();
qDebug() << "HEADER: " << sqlModel->headerData(1, Qt::Horizontal).toString();
And this is what I get from the output
This is what I have in my ListView in QML:
ListView {
id: listaUsuarios
model: sqlModel
delegate:
Text{
anchors.fill: parent
text: nombre
}
}

How to observe the fields of the table are not roles, so they can not be accessed from QML, so to be accessed, the name of the fields must be added as a role, for this the class must be overwritten:
class SqlQueryModel: public QSqlQueryModel{
public:
using QSqlQueryModel::QSqlQueryModel;
QVariant data(const QModelIndex &index, int role) const
{
QVariant value;
if (index.isValid()) {
if (role < Qt::UserRole) {
value = QSqlQueryModel::data(index, role);
} else {
int columnIdx = role - Qt::UserRole - 1;
QModelIndex modelIndex = this->index(index.row(), columnIdx);
value = QSqlQueryModel::data(modelIndex, Qt::DisplayRole);
}
}
return value;
}
QHash<int, QByteArray> roleNames() const
{
QHash<int, QByteArray> roles = QSqlQueryModel::roleNames();
for (int i = 0; i < this->record().count(); i ++) {
roles.insert(Qt::UserRole + i + 1, record().fieldName(i).toUtf8());
}
return roles;
}
};
Example:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlQueryModel>
#include <QSqlRecord>
#include <QDebug>
static bool createConnection()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(":memory:");
if (!db.open()) {
qDebug()<<"Unable to establish a database connection.\n"
"This example needs SQLite support. Please read "
"the Qt SQL driver documentation for information how "
"to build it.\n\n"
"Click Cancel to exit.";
return false;
}
QSqlQuery query;
query.exec("create table usuarios (ID INTEGER PRIMARY KEY AUTOINCREMENT, "
"nombre VARCHAR(20), apellido VARCHAR(20))");
query.exec("insert into usuarios values(1, 'Danny', 'Young')");
query.exec("insert into usuarios values(2, 'Christine', 'Holand')");
query.exec("insert into usuarios values(3, 'Lars', 'Gordon')");
query.exec("insert into usuarios values(4, 'Roberto', 'Robitaille')");
query.exec("insert into usuarios values(5, 'Maria', 'Papadopoulos')");
return true;
}
class SqlQueryModel: public QSqlQueryModel{
public:
using QSqlQueryModel::QSqlQueryModel;
QVariant data(const QModelIndex &index, int role) const
{
QVariant value;
if (index.isValid()) {
if (role < Qt::UserRole) {
value = QSqlQueryModel::data(index, role);
} else {
int columnIdx = role - Qt::UserRole - 1;
QModelIndex modelIndex = this->index(index.row(), columnIdx);
value = QSqlQueryModel::data(modelIndex, Qt::DisplayRole);
}
}
return value;
}
QHash<int, QByteArray> roleNames() const
{
QHash<int, QByteArray> roles = QSqlQueryModel::roleNames();
for (int i = 0; i < this->record().count(); i ++) {
roles.insert(Qt::UserRole + i + 1, record().fieldName(i).toUtf8());
}
return roles;
}
};
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
if(!createConnection())
return -1;
SqlQueryModel sqlModel;
sqlModel.setQuery("SELECT usuarios.nombre FROM usuarios");
qDebug() << sqlModel.roleNames();
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("sqlModel", &sqlModel);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
Output:

Related

Why do I get false when I try to insert a record to a QSqlTableModel in QT?

I'm creating a QSqlRecord object and then I set the values to that QSqlRecord object. But even if I insert the QSqlRecord object to the QSqlTableModel object, the function of inserting records, returns false.
I have this C++ code and it create a QSqlRecord object and set the values. It setting the values in the correct indexed order as how the table was created.
/* Insert data */
int column_index = 0; /* Index 0 is the ID column */
QSqlRecord record;
qDebug() << CALIBRATION_COLUMNS.at(column_index).first;
record.setValue(CALIBRATION_COLUMNS.at(column_index++).first, 1); /* ID */
qDebug() << CALIBRATION_COLUMNS.at(column_index).first;
record.setValue(CALIBRATION_COLUMNS.at(column_index++).first, calibration_id);
qDebug() << CALIBRATION_COLUMNS.at(column_index).first;
record.setValue(CALIBRATION_COLUMNS.at(column_index++).first, calibration_comment);
qDebug() << CALIBRATION_COLUMNS.at(column_index).first;
record.setValue(CALIBRATION_COLUMNS.at(column_index++).first, calibration_date_time);
for(int i = 0; i < 12; i++){
record.setValue(CALIBRATION_COLUMNS.at(column_index++).first, min_adc[i]);
record.setValue(CALIBRATION_COLUMNS.at(column_index++).first, max_adc[i]);
record.setValue(CALIBRATION_COLUMNS.at(column_index++).first, bias_adc[i]);
}
for(int i = 0; i < 5; i++){
record.setValue(CALIBRATION_COLUMNS.at(column_index++).first, min_dadc[i]);
record.setValue(CALIBRATION_COLUMNS.at(column_index++).first, max_dadc[i]);
record.setValue(CALIBRATION_COLUMNS.at(column_index++).first, bias_dadc[i]);
}
for(int i = 0; i < 2; i++)
record.setValue(CALIBRATION_COLUMNS.at(column_index++).first, pulses_per_revolution_encoder[i]);
/* -1 means append record */
qDebug() << calibration_model->insertRecord(-1, record);
qDebug() << calibration_model->lastError().text();
qDebug() << "Submit:";
if(!calibration_model->submitAll()){
qDebug() << calibration_model->lastError().text();
return DATABASE_STATUS_COULD_NOT_INSERT_ROW;
}
return DATABASE_STATUS_OK;
But even if I insert the record, this function calibration_model->insertRecord(-1, record); returns false but the calibration_model->submitAll() returns true.
Output:
"ID"
"calibration_id"
"calibration_comment"
"calibration_date_time"
false
"No Fields to update"
Submit:
So tell me. What I'm I doing wrong here?
I'm getting the error No Fields to update, but what does that mean? I have an empty table and I just want to append with one row.
Not sure why you're getting that error. I have a small example for QSqlTableModel. Let me put it here. Maybe you could compare with your code.
main.cpp
#include <QApplication>
#include "mysqltablemodel.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("mydb");
if(!db.open()) {
qDebug() << db.lastError().text();
return 0;
}
QSqlQuery query(db);
if(!query.exec("DROP TABLE IF EXISTS mytable")) {
qDebug() << "create table error: " << query.lastError().text();
return 0;
}
if(!query.exec("CREATE TABLE IF NOT EXISTS mytable \
(id integer primary key autoincrement, name varchar(15), salary integer)")) {
qDebug() << "create table error: " << query.lastError().text();
return 0;
}
MySqlTableModel *model = new MySqlTableModel(0, db);
model->setTable("mytable");
model->setEditStrategy(QSqlTableModel::OnManualSubmit);
model->select();
QSqlRecord rec = model->record();
rec.setValue(1, "peter");
rec.setValue(2, 100);
qDebug() << model->insertRecord(-1, rec);
rec.setValue(1, "luke");
rec.setValue(2, 200);
qDebug() << model->insertRecord(-1, rec);
if(model->submitAll()) {
model->database().commit();
} else {
model->database().rollback();
qDebug() << "database error: " << model->lastError().text();
}
query.exec("SELECT name, salary FROM mytable");
while (query.next()){
QString name = query.value(0).toString();
int salary = query.value(1).toInt();
qDebug() << name << salary;
}
return app.exec();
}
mysqltablemodel.h
#ifndef MYSQLTABLEMODEL_H
#define MYSQLTABLEMODEL_H
#include <QSqlTableModel>
#include <QSqlRecord>
#include <QSqlError>
#include <QSqlQuery>
#include <QDebug>
class MySqlTableModel : public QSqlTableModel
{
Q_OBJECT
public:
MySqlTableModel(QObject *parent = 0, QSqlDatabase db = QSqlDatabase());
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole ) const;
protected:
QHash<int, QByteArray> roleNames() const;
private:
QHash<int, QByteArray> roles;
};
#endif // MYSQLTABLEMODEL_H
mysqltablemodel.cpp
#include "mysqltablemodel.h"
MySqlTableModel::MySqlTableModel(QObject *parent, QSqlDatabase db): QSqlTableModel(parent, db) {}
QVariant MySqlTableModel::data ( const QModelIndex & index, int role ) const
{
if(index.row() >= rowCount()) {
return QString("");
}
if(role < Qt::UserRole) {
return QSqlQueryModel::data(index, role);
}
else {
return QSqlQueryModel::data(this->index(index.row(), role - Qt::UserRole), Qt::DisplayRole);
}
}
QHash<int, QByteArray> MySqlTableModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[Qt::UserRole + 1] = "name";
roles[Qt::UserRole + 2] = "salary";
return roles;
}

qcombobox do not display current text when choose item

I have a QComboBox connect to model and display list of text item from model, but when I choose one of its item, QComboBox display item text, but when I click on other widget (QComboBox lost focus), current text become empty
cboProfiles->setModel(QComboBoxModel);
cboProfiles->setModelColumn(0);
cboProfiles->setEditable(true);
follow is my model QComboBoxModel.h
#ifndef QCOMBOBOXMODEL_H
#define QCOMBOBOXMODEL_H
#include <QModelIndex>
class QComboBoxModel : public QAbstractListModel
{
public:
QComboBoxModel(QObject *parent=nullptr);
int rowCount(const QModelIndex &) const;
QVariant data(const QModelIndex &index, int role) const;
void populate(const QList<QPair<int,QString>> &values);
void append(int index, QString value);
private:
QList<QPair<int,QString>> values;
};
#endif // QCOMBOBOXMODEL_H
here is QComboBoxModel.cpp
#include "qcomboboxmodel.h"
#include <QModelIndex>
QComboBoxModel::QComboBoxModel(QObject *parent)
:QAbstractListModel(parent)
{
}
int QComboBoxModel::rowCount(const QModelIndex &) const
{
return values.count();
}
QVariant QComboBoxModel::data( const QModelIndex &index, int role ) const
{
QVariant value;
switch ( role )
{
case Qt::DisplayRole: //string
{
value = this->values.value(index.row()).second;
}
break;
case Qt::UserRole: //data
{
value = this->values.value(index.row()).first;
}
break;
default:
break;
}
return value;
}
void QComboBoxModel::populate(const QList<QPair<int,QString>> &values)
{
this->values = values;
}
void QComboBoxModel::append(int index, QString value)
{
int newRow = this->values.count();
this->beginInsertRows(QModelIndex(), newRow, newRow);
values.append(QPair<int, QString>(index, value));
endInsertRows();
}
here is my use code:
QComboBox* combobox = new QComboBox;
QList<QPair<int, QString>> values;
values.append(QPair<int, QString>(-1, "Select item"));
values.append(QPair<int, QString>(10, "item1(0)"));
values.append(QPair<int, QString>(11, "item1(1)"));
values.append(QPair<int, QString>(21, "item1(2)"));
values.append(QPair<int, QString>(32, "item1(3)"));
values.append(QPair<int, QString>(44, "item1(4)"));
QComboBoxModel *model = new QComboBoxModel();
model->populate(values);
combobox->setModel(model);
combobox->setEditable(true);

How to add items to the map from coordinates in the database?

I have a database with the coordinates of the airports and I need to display them with points on the map (QtLocation).
With the QSqlQueryModel I can easily populate and show a TableView, but I have no idea how to create MapQuickItems.
class SqlModel : public QSqlQueryModel
{
Q_OBJECT
public:
enum Roles {
LatitudeRole = Qt::UserRole + 1,
LongitudeRole = Qt::UserRole + 2
};
explicit SqlModel(QObject *parent = nullptr) : QSqlQueryModel(parent) {}
QVariant data(const QModelIndex &index, int role) const override
{
int columnId = role - Qt::UserRole - 1;
QModelIndex modelIndex = this->index(index.row(), columnId);
return QSqlQueryModel::data(modelIndex, Qt::DisplayRole);
}
protected:
QHash<int, QByteArray> roleNames() const override {
QHash<int, QByteArray> roles;
roles[LatitudeRole] = "latitude";
roles[LongitudeRole] = "longitude";
return roles;
}
};
in main.cpp:
//...
SqlModel *model = new SqlModel;
model->setQuery("SELECT air_latitude, air_longitude FROM tab_airports");
engine.rootContext()->setContextProperty("myModel", model);
//...
Using the SqlQueryModel of my previous answer that allows to obtain the data through the roles that have the same name of the fields and transforming it to QCoordinate using QtPositioning.coordinate in a MapItemView that is delegated to the MapQuickItem the following is obtained:
#include <QtGui>
#include <QtSql>
#include <QtQml>
class SqlQueryModel : public QSqlQueryModel {
Q_OBJECT
public:
using QSqlQueryModel::QSqlQueryModel;
QHash<int, QByteArray> roleNames() const {
QHash<int, QByteArray> roles;
for (int i = 0; i < record().count(); i++) {
roles.insert(Qt::UserRole + i + 1, record().fieldName(i).toUtf8());
}
return roles;
}
QVariant data(const QModelIndex &index, int role) const {
QVariant value;
if (index.isValid()) {
if (role < Qt::UserRole) {
value = QSqlQueryModel::data(index, role);
} else {
int columnIdx = role - Qt::UserRole - 1;
QModelIndex modelIndex = this->index(index.row(), columnIdx);
value = QSqlQueryModel::data(modelIndex, Qt::DisplayRole);
}
}
return value;
}
};
static bool createConnection(const QString &path) {
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(path);
if (!db.open()) {
qDebug() << "Cannot open database\n"
"Unable to establish a database connection.\n"
"This example needs SQLite support. Please read "
"the Qt SQL driver documentation for information how "
"to build it.\n\n"
"Click Cancel to exit.";
return false;
}
return true;
}
static void createData(){
QSqlQuery query;
query.exec("CREATE TABLE IF NOT EXISTS tab_airports(air_latitude REAL, air_longitude REAL)");
for(int i=0; i<10; i++){
query.prepare("INSERT INTO tab_airports(air_latitude, air_longitude) VALUES (?, ?)");
double lat = 59.91 + .02 * (QRandomGenerator::global()->generateDouble() - .5);
double lng = 10.75 + .02 * (QRandomGenerator::global()->generateDouble() - .5);
query.addBindValue(lat);
query.addBindValue(lng);
query.exec();
}
}
int main(int argc, char *argv[]) {
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
if (!createConnection(":memory:"))
return -1;
createData();
SqlQueryModel model;
model.setQuery("SELECT air_latitude, air_longitude FROM tab_airports");
engine.rootContext()->setContextProperty("airport_model", &model);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
#include "main.moc"
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtLocation 5.11
import QtPositioning 5.11
ApplicationWindow {
id: root
visible: true
width: 640
height: 480
Plugin {
id: mapPlugin
name: "osm"
}
Map {
id: map
anchors.fill: parent
plugin: mapPlugin
center: QtPositioning.coordinate(59.91, 10.75) // Oslo
zoomLevel: 14
MapItemView{
id: view
model: airport_model
delegate: MapQuickItem{
coordinate: QtPositioning.coordinate(model.air_latitude, model.air_longitude)
anchorPoint.x: image.width/2
anchorPoint.y: image.height
sourceItem: Image {
id: image
source: "http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_red.png"
}
}
}
}
}

change c++ QAbstractListModel values from Qml

this is my code
devicemodel.h
class Device
{
public:
Device(const int &nodeId ,const QString &type, const int &lampVoltage);
//![0]
QString type() const;
int lampVoltage() const;
int nodeId() const;
public:
QString m_type;
int m_lampVoltage;
int m_nodeId;
//![1]
};
class DeviceModel : public QAbstractListModel
{
Q_OBJECT
public:
enum DeviceRoles {
NodeIdRole = Qt::UserRole + 1,
TypeRole ,
LampVoltageRole
};
DeviceModel(QObject *parent = 0);
//![1]
void addDevice(const Device &Device);
int rowCount(const QModelIndex & parent = QModelIndex()) const;
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
protected:
QHash<int, QByteArray> roleNames() const;
private:
QList<Device> m_Devices;
//![2]
public slots :
void callFromQml(int index);
};
devicemodel.cpp
Device::Device(const int &nodeId ,const QString &type, const int &lampVoltage)
: m_nodeId(nodeId) , m_type(type), m_lampVoltage(lampVoltage)
{
}
QString Device::type() const
{
return m_type;
}
int Device::nodeId() const
{
return m_nodeId;
}
int Device::lampVoltage() const
{
return m_lampVoltage;
}
DeviceModel::DeviceModel(QObject *parent)
: QAbstractListModel(parent)
{
}
void DeviceModel::callFromQml(int index){
Device k= m_Devices.at(index);
qDebug() << k.type() << k.lampVoltage();
k.m_lampVoltage = 5;
emit dataChanged(createIndex(index,0), createIndex(index,0), {0,1,2} );
}
void DeviceModel::addDevice(const Device &Device)
{
beginInsertRows(QModelIndex(), rowCount(), rowCount());
m_Devices << Device;
endInsertRows();
}
int DeviceModel::rowCount(const QModelIndex & parent) const {
Q_UNUSED(parent);
return m_Devices.count();
}
QVariant DeviceModel::data(const QModelIndex & index, int role) const {
if (index.row() < 0 || index.row() >= m_Devices.count())
return QVariant();
const Device &Device = m_Devices[index.row()];
if (role == NodeIdRole)
return Device.nodeId();
else if (role == TypeRole)
return Device.type();
else if (role == LampVoltageRole)
return Device.lampVoltage();
return QVariant();
}
//![0]
QHash<int, QByteArray> DeviceModel::roleNames() const {
QHash<int, QByteArray> roles;
roles[NodeIdRole] = "nodeId";
roles[TypeRole] = "type";
roles[LampVoltageRole] = "lampVoltage";
return roles;
}
main.qml
ListView {
width: 200; height: 250
spacing: 10
model: myModel
delegate:
Text { text: "Animal: " + type + ", " + lampVoltage
MouseArea {
anchors.fill: parent
onClicked: {
console.log("egwegweg");
myModel.callFromQml(index);
//lampVoltage = 10;
// myModel.setData(index , 10 , 2);
}
}
}
}
main.cpp
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
DeviceModel model;
model.addDevice(Device(1, "Medium" , 200));
model.addDevice(Device(1, "Medium" , 200));
model.addDevice(Device(1, "Medium" , 200));
QQmlContext *ctxt = engine.rootContext();
ctxt->setContextProperty("myModel", &model);
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
model.addDevice(Device(1, "Medium" , 200));
model.addDevice(Device(1, "Medium" , 200));
model.addDevice(Device(1, "Medium" , 200));
return app.exec();
i want modify my item values from Qml
i wrote a slot named callFromQml and pass index of item from qml to c++ code and want update the values from it
but can not do it
i don not know emit signal works or not and do not know pass index to it correctly or not and don not
Thanks for #MarkCh for pointing out, that you have not reimplemented the setData()-method.
The signature is:
bool QAbstractItemModel::setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole)
It returns true if some data was set successfully, and false if not.
Further, uppon success, before returning, it is necessary to emit dataChanged(...) so any views will be aware of the change.
Let's do it:
Add the appropriate declaration to the header file
Add the implementation to the .cpp-file. This might look like this:
bool QAbstractItemModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (index.row() < 0 || index.row() >= m_Devices.count())
return false;
const Device &Device = m_Devices[index.row()];
if (role == NodeIdRole) {
Device.m_nodeId = value.toInt();
emit dataChanged(index, index);
return true;
}
else if (role == TypeRole) {
Device.m_type = value.toString();
emit dataChanged(index, index);
return true;
}
else if (role == LampVoltageRole) {
Device.m_lampVoltage = value.toInt();
emit dataChanged(index, index);
return true;
}
return false;
}
Make DeviceModel a friend of Device or change the access of the private fields to usage of getters. As you like.
Now you should be able to set the roles in the delegate as if they were properties... Like:
onClicked: model.nodeId = 100;
The code above is not tested, but should include the most relevant details.

Qt Quick returning objects from roles

I'm trying to get a role to return an object. I'm running into undefined errors when I try to access display.blockNumber and display.time
here's my code
blockdisplay.h:
#ifndef BLOCKDISPLAY_H
#define BLOCKDISPLAY_H
#include <QMetaType>
class BlockDisplay
{
public:
BlockDisplay();
BlockDisplay(int blocknum, long time);
BlockDisplay(const BlockDisplay &other);
~BlockDisplay();
int blockNumber() const;
long time() const;
private:
int m_blocknumber;
long m_time;
};
Q_DECLARE_METATYPE(BlockDisplay)
#endif // BLOCKDISPLAY_H
blockdisplay.cpp:
#include "blockdisplay.h"
BlockDisplay::BlockDisplay() {
}
BlockDisplay::BlockDisplay(int blocknum, long time) {
this->m_blocknumber = blocknum;
this->m_time = time;
}
BlockDisplay::BlockDisplay(const BlockDisplay &other) {
this->m_blocknumber = other.blockNumber();
this->m_time = other.time();
}
BlockDisplay::~BlockDisplay() {
}
int BlockDisplay::blockNumber() const {
return this->m_blocknumber;
}
long BlockDisplay::time() const {
return this->m_time;
}
modelclass.h:
#ifndef MODELCLASS_H
#define MODELCLASS_H
#include <QObject>
#include <QAbstractListModel>
#include <QStringListModel>
#include <blockchain.h>
class ModelClass : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(qint32 blockheight READ blockheight)
protected:
Blockchain bc{};
int first;
public:
ModelClass();
qint32 blockheight();
void init();
int rowCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
};
#endif // MODELCLASS_H
modelclass.cpp:
#include "modelclass.h"
#include <string.h>
#include <qdebug>
#include "blockdisplay.h"
using namespace std;
ModelClass::ModelClass()
{
}
void ModelClass::init() {
bc.init();
if ( !bc.Valid() )
qDebug() << "invalid";
else {
bc.SeekToFirst();
bc.Next();
if ( !bc.Valid() )
qDebug() << "invalid";
else
first = bc.GetCurrentBlock().signedhead().head().num();
}
//setProperty("blockheight",bc.GetBlockHeight());
}
qint32 ModelClass::blockheight() {
return bc.GetBlockHeight();
}
int ModelClass::rowCount(const QModelIndex &parent) const {
//qInfo() << " 0test " << bc.GetBlockHeight();
return bc.GetBlockHeight() - first;
}
QVariant ModelClass::data(const QModelIndex & index, int role) const {
qInfo() << " 1test " << index;
int row = bc.GetBlockHeight() - index.row();// + 1 + first;
if (index.isValid()) {
bc.Seek(row);
if (bc.Valid()) {
if (role == Qt::DisplayRole) {
int blocknum = bc.GetCurrentBlock().signedhead().head().num();
long timestamp = bc.GetCurrentBlock().signedhead().head().timestamp();
BlockDisplay dsply{blocknum, timestamp};
QVariant var = QVariant::fromValue(dsply);
return var;
}
}
}
return QVariant();
}
snippet from block.qml:
Component {
id: gridComp
Row {
Text {
text: display.blockNumber + " "
MouseArea {
anchors.fill: parent
onClicked: {
list.currentIndex = index;
ld.setSource("detail.qml")
}
}
}
Text {
text: display.time + " "
}
}
}
I think Q_DECLARE_METATYPE(BlockDisplay) is not enough. If you want to use its attributes in QML you have to use the Q_PROPERTY macro to create properties, just like you did for ModelClass. You may also have to call qRegisterMetaType
Adding a Q_DECLARE_METATYPE() makes the type known to all template based functions, including QVariant. Note that if you intend to use the type in queued signal and slot connections or in QObject's property system, you also have to call qRegisterMetaType() since the names are resolved at runtime.

Resources