Почему это не добавляет QObject * в QVector - PullRequest
1 голос
/ 09 июля 2020

У меня две модели просмотра: MainVM и AddVM. В main.cpp, MainVM объявляется так:

MainVM *mvm;    
int main(int argc, char *argv[])
{
    ...
    mvm = new MainVM();
    ...
    engine.rootContext()->setContextProperty("mainContext", mvm);
    engine.rootContext()->setContextProperty("addContext", new AddVM());
    ...
}

, а в MainVM есть этот Q_PROPERTY:

class MainVM : public QObject
{
    Q_OBJECT
    ...
    PROPERTY(QVector<Plot*>, plots)
    ...
public:
    ...
    QSqlDatabase db;
    int maxPlotId, maxSpaceId, maxTenantId, maxHeadId, maxLeaseId;
    ...
};

макрос PROPERTY делает это:

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

В моем AddVM у меня есть еще Q_PROPERTY newPlot и Q_INVOKABLE addNewPlot:

class AddVM : public QObject
{
    Q_OBJECT
    PROPERTY(Plot*, newPlot)
public:
    explicit AddVM(QObject *parent = nullptr);
    Q_INVOKABLE void addNewPlot();
}; 

поверх AddVM.cpp, я Вот эти:

#include "MainVM.h"
extern MainVM *mvm;

и addNewPlot функции имеют следующие инструкции:

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

все в этой функции работает должным образом, кроме строки mvm->plots().push_back(newPlot());! Это не добавляет newPlot в QVector из MainVM!

EDIT

Вероятно, лучший способ - переопределить getter в макрос вроде этого:

QType& name(){return m_##name;} \

и с этим мой существующий код работает без каких-либо изменений.

1 Ответ

0 голосов
/ 09 июля 2020

Когда вы вызываете mvm->plots(), он возвращает копию реального вектора графиков (это мое предположение, потому что вы не показали, что делает plots()). Таким образом, к копии добавляется новый график, а не исходный вектор. Итак, я думаю, что лучший способ - добавить функцию в MainVM, которая называется 'addPlot ()', например, где вы можете добавить к графику вектор внутренне и напрямую.

...