Do I have to delete these QObject* when I reset QVector<QObject*>

烂漫一生 提交于 2020-07-23 06:52:26

问题


Here's one of my ViewModels:

class MainVM : public QObject
{
    Q_OBJECT
    PROPERTY(QVector<View*>, views)

    // Created with new operator from database
    PROPERTY(QVector<Plot*>, plots)
    PROPERTY(QVector<Space*>, spaces)
    PROPERTY(QVector<Tenant*>, tenants)
    PROPERTY(QVector<ControlHead*>, controlHeads)
    PROPERTY(QVector<Head*>, heads)   
    PROPERTY(QVector<Lease*>, leases)
    PROPERTY(QVector<Receivable*>, receivables)

    PROPERTY(QVector<Space*>, filteredSpaces) // adds few pointers from PROPERTY(QVector<Space*>, spaces)
    PROPERTY(QVector<Head*>, filteredHeads)   // adds few pointers from PROPERTY(QVector<Head*>, heads)
    PROPERTY(QVector<Head*>, receivableHeads) // adds few pointers from PROPERTY(QVector<Head*>, heads)

    PROPERTY(int, selectedPlot)
    PROPERTY(int, selectedSpace)
    PROPERTY(int, selectedTenant)
    PROPERTY(int, selectedHead)
    PROPERTY(int, selectedLease)

public:
    explicit MainVM(QObject *parent = nullptr);
    QSqlDatabase db;
    int maxPlotId, maxSpaceId, maxTenantId, maxHeadId, maxLeaseId;

private:
    void createDatabase();
    void fillVectors();
    void setMaxIds();
    template<class T> int getMaxId(QVector<T> &vec);
    void setSelected();
    void hookupSignalSlot();

private slots:
    void onSelectedPlotChanged();
};

First seven PROPERTY, except views, are created with new operator. For example spaces is filled in this way:

while (query.next()) {
    auto space = new Space();
    space->setid(query.value(0).toInt());
    space->setplotId(query.value(1).toInt());
    space->setname(query.value(2).toString());
    space->setdescription(query.value(3).toString());
    space->setisVacant(query.value(4).toBool());
    m_spaces.push_back(space);
}

the PROPERTY(int, selectedPlot) can be set both ways, in my qml, for the combobox associated with PROPERTY(QVector<Plot*>, plots), I've these:

Binding{
    target: mainContext
    property: "selectedPlot"
    value: c3.currentIndex
}
Binding{
    target: c3
    property: "currentIndex"
    value: mainContext.selectedPlot
}

in the slot onSelectedPlotChanged I've these:

void MainVM::onSelectedPlotChanged()
{
    m_filteredSpaces.clear();
    auto plotId = m_plots[m_selectedPlot]->id(); 
    for(int i = 0; i < m_spaces.size(); i++){
        if(m_spaces[i]->plotId() == plotId)
            m_filteredSpaces.push_back(m_spaces[i]);
    }
    emit filteredSpacesChanged();
    if(m_filteredHeads.size() > 0)
        setselectedSpace(m_filteredSpaces.first()->id());
}

it just clears the QVector associated with PROPERTY(QVector<Space*>, filteredSpaces) and adds pointers from PROPERTY(QVector<Space*>, spaces). All of my data structures for ViewModels are defined in this way:

class Space : public QObject{
    Q_OBJECT
    PROPERTY(int, id)
    PROPERTY(int, plotId)
    PROPERTY(QString, name)
    PROPERTY(QString, description)
    PROPERTY(bool, isVacant)
}; 

and this is the macro I'm using for Q_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;

Do I have to do anything more for properties that borrows pointers from its siblings OR I'm on the right track?

EDIT

I actually don't need two separate Binding objects for two way binding between c++ and qml, this works:

currentIndex: mainContext.selectedPlot
onCurrentIndexChanged: mainContext.selectedPlot = currentIndex

来源:https://stackoverflow.com/questions/62787149/do-i-have-to-delete-these-qobject-when-i-reset-qvectorqobject

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!