Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Clean QList for QMLListProperty
QtWS25 Last Chance

Clean QList for QMLListProperty

Scheduled Pinned Locked Moved Solved General and Desktop
qmllistpropertyqlistdeleteclearqdeleteall
3 Posts 2 Posters 2.2k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Alart
    wrote on 8 Mar 2016, 18:51 last edited by
    #1

    Hi,

    I have container QObject that contains QList of QObjects. I use it in QmlListProperty and show it in application.
    I want to rewrite that list in function. So I clear list and append things again.

    m_list_Qobjects.clear;
    for ()
        m_list_Qobjects.append(new Qobject);
    emit listQobjectsChanged(list_Qobject());
    

    And it works, but obviously memory leaks, because clear() doesn't call delete for stored pointers.

    I tried to delete it:

    qDeleteAll(m_list_Qobjects);
    m_list_Qobjects.clear(); // It doesn't matter already I think
    for ()
        m_list_Qobjects.append(new myQobject);
    emit listQobjectsChanged(list_Qobject());
    

    But my application crashes.
    So I thought about another way to solve it, I simply copied pointers to delete them later:

    QList<myQobject *> delList = m_list_Qobjects;
    m_list_Qobjects.clear(); //now it's crucial
    for ()
        m_list_Qobjects.append(new myQobject);
    emit listQobjectsChanged(list_Qobject());
    qDeleteAll(delList); // it stops leaks
    

    And it actually works. So I tried to make list of those containers (list of lists):

    QList<listQobject *> delList = m_list_listQobjects;
    m_list_of_listQobjects.clear;
    for ()
        m_list_of_listQobjects.append(new listQobject);
    emit m_list_of_listQobjectsChanged(m_list_of_listQobjects());
    qDeleteAll(delList);
    

    But it crashes again.

    So probably solution wasn't so great at all...
    I suppose there must be some way to safely clean after unnecessary pointers from QList/QmlListProperty.

    I prepared small program to work on that problem specifically, but I'm not sure if should I paste whole project.

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 8 Mar 2016, 22:25 last edited by
      #2

      Hi,

      AFAIK, the QML engine will take ownership of QObjects without parent (see here) so what is likely to happen is that you are deleting object that are not yours to delete. To avoid that give your objects a parent.`

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      1
      • A Offline
        A Offline
        Alart
        wrote on 12 Mar 2016, 01:18 last edited by Alart
        #3

        However I did certainly what you said that was only little part.
        Thank for your answer, without it I would only find a way around this issue probably. (like 2 parallel QLists)

        So what works?

        • I make additional QObject with parent "this (list of lists)".
        • Then I make it parent of every QObject I want to delete (QObjects with list and QObjects within lists). I don't change CppOwnership.
        • After that I clear() list and add new QObjects (obsolete QObjects stay accessible as children of that additional QObject).
        • After final emit I delete that QObject with deleteLater(). QPointer isn't necessary here I think. I tried deleteLater in another way of doing things and it crashed, so that is the only way I found.
        • My application deletes QObject and all children with it. With neither crash or leak.
        QObject * delQObject = new QObject (this);
        set_parents_list(delQObject );
        m_list_of_listQobjects.clear();
        for ()
            m_list_of_listQobjects.append(new listQobject);
        emit m_list_of_listQobjectsChanged(m_list_of_listQobjects());
        delQObject->deleteLater();
        

        where:

        listoflistsofQObjects :: set_parents_list(QObject * parent) {
        	for (int i = m_list_of_listQobjects.count(); i>0; i--) {
        		m_list_of_listQobjects[i-1]->setParent(parent);
        		m_list_of_listQobjects[i-1]->set_parents_list(parent);
        	}
        }
        

        Following function isn't necessary if QObjects already have parent that is deleted (like listofQObjects or some QObject inside it). It's safer to make elements children, because then one doesn't need to call deletes in destructor.

        listofQObjects :: set_parents_list(QObject * parent) {
        	for (int i = m_list_ofQobjects.count(); i>0; i--) {
        		m_list_ofQobjects[i-1]->setParent(parent);
        	}
        }
        

        I don't know if is it "right way", I even found here somebody uses my earlier version with additional list (but it's unsafe for sure).

        The best explanation how to manage memory in qt I found here.

        If there is better way to do so, please share.

        1 Reply Last reply
        0

        3/3

        12 Mar 2016, 01:18

        • Login

        • Login or register to search.
        3 out of 3
        • First post
          3/3
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved