I can emit signals with structs tagged with Q_GADGET from C++ to QML.
Is it possible send such a struct from QML to a C++ slot? My code fails on the first step: creating an instance in QML.
This code fails on the first line ...
var bs = new BatteryState()
bs.percentRemaining = 1.0
bs.chargeDate = new Date()
DataProvider.setBatteryState(bs)
... with error:
qrc:///main.qml:34: ReferenceError: BatteryState is not defined
I can emit a BatteryStatus struct from C++ to QML, but I would like to send one back as a single parameter to a slot.
Here is BatteryState.h & BatteryState.cpp:
// BatteryState.h
#pragma once
#include <QDate>
#include <QMetaType>
struct BatteryState
{
Q_GADGET
Q_PROPERTY(float percentRemaining MEMBER percentRemaining)
Q_PROPERTY(QDate date MEMBER date)
public:
explicit BatteryState();
BatteryState(const BatteryState& other);
virtual ~BatteryState();
BatteryState& operator=(const BatteryState& other);
bool operator!=(const BatteryState& other) const;
bool operator==(const BatteryState& other) const;
float percentRemaining;
QDate date;
};
Q_DECLARE_METATYPE(BatteryState)
// BatteryState.cpp
#include "BatteryState.h"
BatteryState::BatteryState()
: percentRemaining(), date(QDate::currentDate())
{}
BatteryState::BatteryState(const BatteryState& other)
: percentRemaining(other.percentRemaining),
date(other.date)
{}
BatteryState::~BatteryState() {}
BatteryState&BatteryState::operator=(const BatteryState& other)
{
percentRemaining = other.percentRemaining;
date = other.date;
return *this;
}
bool BatteryState::operator!=(const BatteryState& other) const {
return (percentRemaining != other.percentRemaining
|| date != other.date);
}
bool BatteryState::operator==(const BatteryState& other) const {
return !(*this != other);
}
I register this type in main.cpp:
qRegisterMetaType<BatteryState>();
Recommendations?
You don't create Q_GADGET
s in QML, QML objects need to be QObject
derived, and are not created via new
- that's for JS objects only. Gadgets just generate meta data so that you can access their members and such from QML and pass around, that's about it.
Is it possible send such a struct from QML to a C++ slot?
It is possible to send, but it would not be created in QML. It could be returned to QML from a C++ function or be exposed as a property of some object.
struct Test {
Q_GADGET
Q_PROPERTY(int test MEMBER test)
public:
Test() : test(qrand()) {}
int test;
Q_SLOT void foo() { qDebug() << "foo"; }
};
class F : public QObject { // factory exposed as context property F
Q_OBJECT
public slots:
Test create() { return Test(); }
void use(Test t) { qDebug() << t.test; }
};
// from QML
property var tt: F.create()
Component.onCompleted: {
F.use(F.create()) // works
var t = F.create()
console.log(t.test) // works
F.use(t) // works
console.log(tt.test) // works
F.use(tt) // works
tt.test = 555
F.use(tt) // works
t.test = 666
F.use(t) // works
t.foo() // works
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With