Need advise on memory management/garbage collection in QAbstractListModel



  • Hi there,

    I'm very new to QT and coming from java memory management is overwhelming for me.

    Here is my plan

    im going to make a QAbstractListModel model, ill use a QList<MyVOObject*> where ill new MyVOObject() and add back to QList. That QList will be use as "source" qlist and ill filter objects from this list and put them in a second list that will appear on ListView. For example show all objects or objects by a single country.

    My question is what pointer should i use? i read somewhere about QSharedPointer but then somewhere i heard that use C++ shared_ptr

    Please advise
    Thanks


  • Moderators

    @scotryder said in Need advise on memory management/garbage collection in QAbstractListModel:

    That QList will be use as "source" qlist and ill filter objects from this list and put them in a second list that will appear on ListView. For example show all objects or objects by a single country.

    You can use QSortFilterProxyModel for that.

    My question is what pointer should i use? i read somewhere about QSharedPointer but then somewhere i heard that use C++ shared_ptr

    It does not matter which you choose, pick one that you prefer. QSharedPointer has an advantage of being a Qt class with nice API. shared_ptr is slightly more performant and you'll learn standard C++ API when you use it.



  • @sierdzio
    Thank you very much :)
    I might have questions regarding integrating it in QML but will post a new question.



  • @scotryder said in Need advise on memory management/garbage collection in QAbstractListModel:

    I might have questions regarding integrating it in QML

    In this case, don't implement QAbstractListModel which is fairly hard, declare MyVOObject as a meta type (if it's not a QObject) and use QStandardItemModel. see this wiki page for an example



  • @VRonin Thanks will look into that :)


  • Moderators

    @VRonin said in Need advise on memory management/garbage collection in QAbstractListModel:

    In this case, don't implement QAbstractListModel which is fairly hard

    It's just a matter of reimplementing data(), roleNames() and setData(), nothing too taxing ;-) Anyway, cool link with QStandardItemModel, thanks for sharing.



  • @sierdzio and insertRows() and removeRows() (using begin and end methods) and buddy() (the one I always forget about)


  • Moderators

    @VRonin said in Need advise on memory management/garbage collection in QAbstractListModel:

    @sierdzio and insertRows() and removeRows() (using begin and end methods) and buddy() (the one I always forget about)

    These do not need to be implemented, unless you actually need them for something. Model will work fine without these methods.

    Anyway, we're derailing the topic a bit, sorry @scotryder :D



  • @sierdzio

    Ok i created a child class of QSortFilterProxyModel and exposed it to QML, but how do i assign my DataModel (already exported to QML as Class)?

    ListView{
    
    model: MySortProxy{
    
    //which property to assing my dataModel
    
    }
    
    }
    

    Sorry, its sourceModel



  • @sierdzio I like derailing. I think you still need rowCount() reimplemented and I'm not sure you can live without buddy()

    @scotryder

    child class of QSortFilterProxyModel

    Not sure what you mean by "child" here.



  • Ok thanks to you both, i finally managed to make my FilterProxyRun (without overrding any methods obviously :P )

    Now my main problem is, how do i apply filters based on multiple fields of my Person class?
    for example, i want to filter list of people by applying filters on age, name, location etc.

    So which method should i override and how i apply multiple filters on roles at once.

    Thanks


  • Moderators



  • Base Class: header, source

    This requires all filters to be satisfied:

    #include "MultipleFilterProxy.h"
    class AndFilterProxy : public MultipleFilterProxy
    {
        Q_OBJECT
        Q_DISABLE_COPY(AndFilterProxy)
    public:
        explicit AndFilterProxy(QObject *parent = Q_NULLPTR) : MultipleFilterProxy(parent)
    {}
    protected:
        bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const Q_DECL_OVERRIDE{    
            for (int i = 0; i < sourceModel()->columnCount(source_parent); ++i) {
                QModelIndex currntIndex = sourceModel()->index(source_row, i, source_parent);
                for (auto dateRngIter = m_dateRangeFilter.at(i).constBegin(); dateRngIter != m_dateRangeFilter.at(i).constEnd(); ++dateRngIter) {
                    const QDate testDate = currntIndex.data(dateRngIter.key()).toDate();
                    if (!((testDate >= dateRngIter.value().first || dateRngIter.value().first.isNull()) && (testDate <= dateRngIter.value().second || dateRngIter.value().second.isNull())))
                        return false;
                    
                }
                for (auto boolIter = m_boolFilter.at(i).constBegin(); boolIter != m_boolFilter.at(i).constEnd(); ++boolIter) {
                    const bool testBool = currntIndex.data(boolIter.key()).toBool();
                    if (testBool != boolIter.value())
                        return false;
                }
                for (auto regExpIter = m_regExpFilter.at(i).constBegin(); regExpIter != m_regExpFilter.at(i).constEnd(); ++regExpIter) {
                    if (regExpIter.value().first.match(currntIndex.data(regExpIter.key()).toString()).hasMatch() != regExpIter.value().second)
                        return false;
                }
            }
        return true;
    }
    };
    

    This requires any filter to be satisfied:

    #include "MultipleFilterProxy.h"
    class OrFilterProxy : public MultipleFilterProxy
    {
        Q_OBJECT
        Q_DISABLE_COPY(OrFilterProxy )
    public:
        explicit OrFilterProxy(QObject *parent = Q_NULLPTR) : MultipleFilterProxy(parent)
    {}
    protected:
        bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const Q_DECL_OVERRIDE{    
            for (int i = 0; i < sourceModel()->columnCount(source_parent); ++i) {
                QModelIndex currntIndex = sourceModel()->index(source_row, i, source_parent);
                for (auto dateRngIter = m_dateRangeFilter.at(i).constBegin(); dateRngIter != m_dateRangeFilter.at(i).constEnd(); ++dateRngIter) {
                    const QDate testDate = currntIndex.data(dateRngIter.key()).toDate();
                    if (((testDate >= dateRngIter.value().first || dateRngIter.value().first.isNull()) && (testDate <= dateRngIter.value().second || dateRngIter.value().second.isNull())))
                        return true;
                    
                }
                for (auto boolIter = m_boolFilter.at(i).constBegin(); boolIter != m_boolFilter.at(i).constEnd(); ++boolIter) {
                    const bool testBool = currntIndex.data(boolIter.key()).toBool();
                    if (testBool == boolIter.value())
                        return true;
                }
                for (auto regExpIter = m_regExpFilter.at(i).constBegin(); regExpIter != m_regExpFilter.at(i).constEnd(); ++regExpIter) {
                    if (regExpIter.value().first.match(currntIndex.data(regExpIter.key()).toString()).hasMatch() == regExpIter.value().second)
                        return true;
                }
            }
        return false;
    }
    };
    


  • @VRonin Thank you very much for such a detailed reply, u r a life saver :)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.