I've two ViewModels, MainVM
and AddVM
. In main.cpp
, MainVM
is declared this way:
MainVM *mvm;
int main(int argc, char *argv[])
{
...
mvm = new MainVM();
...
engine.rootContext()->setContextProperty("mainContext", mvm);
engine.rootContext()->setContextProperty("addContext", new AddVM());
...
}
and in MainVM
, I've this Q_PROPERTY
:
class MainVM : public QObject
{
Q_OBJECT
...
PROPERTY(QVector<Plot*>, plots)
...
public:
...
QSqlDatabase db;
int maxPlotId, maxSpaceId, maxTenantId, maxHeadId, maxLeaseId;
...
};
the PROPERTY
macro does this:
#define PROPERTY(QType, name) \
Q_PROPERTY(QType name READ name WRITE set##name NOTIFY name##Changed) \
public: \
QType name(){return m_##name;} \
void set##name(QType value){if(m_##name != value){m_##name = value; emit name##Changed();}} \
Q_SIGNAL void name##Changed(); \
private: \
QType m_##name;
In my AddVM
I've another Q_PROPERTY
newPlot and a Q_INVOKABLE
addNewPlot:
class AddVM : public QObject
{
Q_OBJECT
PROPERTY(Plot*, newPlot)
public:
explicit AddVM(QObject *parent = nullptr);
Q_INVOKABLE void addNewPlot();
};
on top of the AddVM.cpp
, I've these:
#include "MainVM.h"
extern MainVM *mvm;
and addNewPlot
function has these instructions:
void AddVM::addNewPlot()
{
mvm->db.open();
QSqlQuery query;
query.prepare("INSERT INTO Plots (Name, Description) VALUES(:Name, :Description)");
query.bindValue(":Name", newPlot()->name());
query.bindValue(":Description", newPlot()->description());
query.exec();
mvm->db.close();
mvm->plots().push_back(newPlot());
setnewPlot(new Plot());
newPlot()->setid(++mvm->maxPlotId);
}
everything in this function works as expected except the mvm->plots().push_back(newPlot());
line! This doesn't add the newPlot
in the QVector
of MainVM
!
EDIT
Probably the best way is to redefine the getter
in the macro like this:
QType& name(){return m_##name;} \
and with that my existing code works without any modification.
When you call mvm->plots()
, it returns a copy of the real plots vector (That's my guess because you didn't show what plots()
does). Thus, a new plot is added to the copy not the original vector. So, I think the best way is to add a function in MainVM
that is called 'addPlot()` for example where you can add to the plots vector internally and directly.