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. QStandardItemModel & Deleting

QStandardItemModel & Deleting

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 4 Posters 7.5k 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.
  • S Offline
    S Offline
    shahriar25
    wrote on last edited by
    #1

    Hi, I have a QStandardItemModel and I append rows to it by creating a pointer QStandardItem and I append that to the model.
    when I clear the model with model.clear() the items get removed from the model but the allocated space in ram doesn't get back to the OS (Linux). It seems like the items don't get removed. what am I doing wrong?

    for (int i=0; i<musicLoader->albumRowCount(); ++i)
    {
        QString itemAlbum = musicLoader->albumValue(i,0);
        QString itemArtist = musicLoader->albumValue(i,1);
        QString itemText = QString ("%1\n%2").arg(itemAlbum).arg(itemArtist);
        QPixmap itemIcon(musicLoader->albumValue(i,4));
    
        if (itemIcon.isNull())
            itemIcon = style.defaultArtwork;
    
        itemIcon = itemIcon.scaled(maxImageSize,Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
    
        QStandardItem *item = new QStandardItem(itemIcon,itemText);
        item->setData(0,Qt::UserRole);
        item->setData(itemAlbum,Qt::UserRole+1);
        item->setData(itemArtist,Qt::UserRole+2);
    
        for (int j=0; j<musicLoader->albumTrackRowCount(i); ++j)
        {
            QString insideItemTitle = musicLoader->albumData(i,j,musicLoader->TITLE);
            QString insideItemArtist = musicLoader->albumData(i,j,musicLoader->ARTIST);
            int insideItemTrack = musicLoader->albumData(i,j,musicLoader->TRACK).toInt();
            QString itemText = QString("%1\t%2").arg(QString::number(insideItemTrack),insideItemTitle);
    
            QStandardItem *insideItem = new QStandardItem(itemText);
            insideItem->setData(1,Qt::UserRole);
            insideItem->setData(insideItemTrack,Qt::UserRole+1);
            insideItem->setData(insideItemTitle,Qt::UserRole+2);
            insideItem->setData(insideItemArtist,Qt::UserRole+3);
    
            item->appendRow(insideItem);
        }
    
        albumModel.appendRow(item);
    }
    
    kshegunovK 1 Reply Last reply
    0
    • S shahriar25

      Hi, I have a QStandardItemModel and I append rows to it by creating a pointer QStandardItem and I append that to the model.
      when I clear the model with model.clear() the items get removed from the model but the allocated space in ram doesn't get back to the OS (Linux). It seems like the items don't get removed. what am I doing wrong?

      for (int i=0; i<musicLoader->albumRowCount(); ++i)
      {
          QString itemAlbum = musicLoader->albumValue(i,0);
          QString itemArtist = musicLoader->albumValue(i,1);
          QString itemText = QString ("%1\n%2").arg(itemAlbum).arg(itemArtist);
          QPixmap itemIcon(musicLoader->albumValue(i,4));
      
          if (itemIcon.isNull())
              itemIcon = style.defaultArtwork;
      
          itemIcon = itemIcon.scaled(maxImageSize,Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
      
          QStandardItem *item = new QStandardItem(itemIcon,itemText);
          item->setData(0,Qt::UserRole);
          item->setData(itemAlbum,Qt::UserRole+1);
          item->setData(itemArtist,Qt::UserRole+2);
      
          for (int j=0; j<musicLoader->albumTrackRowCount(i); ++j)
          {
              QString insideItemTitle = musicLoader->albumData(i,j,musicLoader->TITLE);
              QString insideItemArtist = musicLoader->albumData(i,j,musicLoader->ARTIST);
              int insideItemTrack = musicLoader->albumData(i,j,musicLoader->TRACK).toInt();
              QString itemText = QString("%1\t%2").arg(QString::number(insideItemTrack),insideItemTitle);
      
              QStandardItem *insideItem = new QStandardItem(itemText);
              insideItem->setData(1,Qt::UserRole);
              insideItem->setData(insideItemTrack,Qt::UserRole+1);
              insideItem->setData(insideItemTitle,Qt::UserRole+2);
              insideItem->setData(insideItemArtist,Qt::UserRole+3);
      
              item->appendRow(insideItem);
          }
      
          albumModel.appendRow(item);
      }
      
      kshegunovK Offline
      kshegunovK Offline
      kshegunov
      Moderators
      wrote on last edited by kshegunov
      #2

      @shahriar25
      Hello,
      Try this simple test:

      
      QPointer<QStandardItem> item = new QStandardItem(QStringLiteral("testitem"));
      albumModel.appendRow(item);
      albumModel.clear();
      
      if (item)
          qDebug() << "Item is not deleted!";
      else
          qDebug() << "Item is deleted!";
      

      And see what you get in the output pane/terminal window.

      Kind regards.

      Read and abide by the Qt Code of Conduct

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi,

        @kshegunov I think that the question is rather: why after a call to delete doesn't the OS available memory increase.

        Note that you can't use QPointer with QStandardItem, it's not a QObject based class.

        AFAIK, a delete doesn't mean that the memory will instantly be returned to the OS. It might be marked as free but kept in the application's "memory pool" for later re-use.

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

        kshegunovK 1 Reply Last reply
        0
        • SGaistS SGaist

          Hi,

          @kshegunov I think that the question is rather: why after a call to delete doesn't the OS available memory increase.

          Note that you can't use QPointer with QStandardItem, it's not a QObject based class.

          AFAIK, a delete doesn't mean that the memory will instantly be returned to the OS. It might be marked as free but kept in the application's "memory pool" for later re-use.

          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on last edited by
          #4

          @SGaist said:

          I think that the question is rather: why after a call to delete doesn't the OS available memory increase.

          I got that but a few weeks ago I already had this discussion in this forum.
          The short answer would be: "It does" :)

          AFAIK, a delete doesn't mean that the memory will instantly be returned to the OS. It might be marked as free but kept in the application's "memory pool" for later re-use.

          Depends on the heap manager implementation, but generally it does. However, Linux eats up all the memory and caches it, so depending on the inspection tool it might not be directly obvious.

          For example my Debian has exactly at this moment:
          KiB Mem : 16383400 total, 681720 free, 2975152 used, 12726528 buff/cache

          681MB free is a joke for 16GB physical memory, but see the cache? It basically means the OS has appropriated all the memory and cached it, so it's owning it and distributing as it sees fit. That's the reason I posted the test code. If pointer is NULL then everything is fine. :)

          Read and abide by the Qt Code of Conduct

          1 Reply Last reply
          0
          • S Offline
            S Offline
            shahriar25
            wrote on last edited by
            #5

            Hi @kshegunov
            I tried what you said but I got these errors:
            tried this:
            QPointer<QStandardItem> item = new QStandardItem(QStringLiteral("testitem"));

            got these:
            /home/shahriar/Qt5.6.0/5.6/gcc_64/include/QtCore/qsharedpointer_impl.h:705: error: no matching function for call to 'QtSharedPointer::ExternalRefCountData::getAndRef(QStandardItem*&)'
            inline QWeakPointer(X *ptr, bool) : d(ptr ? Data::getAndRef(ptr) : Q_NULLPTR), value(ptr)
            ^

            /home/shahriar/Qt5.6.0/5.6/gcc_64/include/QtCore/qsharedpointer_impl.h:705: error: cannot convert 'QStandardItem*' to 'QObject*' in initialization
            inline QWeakPointer(X *ptr, bool) : d(ptr ? Data::getAndRef(ptr) : Q_NULLPTR), value(ptr)
            ^

            and it points ti this line:
            inline QWeakPointer(X *ptr, bool) : d(ptr ? Data::getAndRef(ptr) : Q_NULLPTR), value(ptr)

            what is this?

            kshegunovK 1 Reply Last reply
            0
            • S shahriar25

              Hi @kshegunov
              I tried what you said but I got these errors:
              tried this:
              QPointer<QStandardItem> item = new QStandardItem(QStringLiteral("testitem"));

              got these:
              /home/shahriar/Qt5.6.0/5.6/gcc_64/include/QtCore/qsharedpointer_impl.h:705: error: no matching function for call to 'QtSharedPointer::ExternalRefCountData::getAndRef(QStandardItem*&)'
              inline QWeakPointer(X *ptr, bool) : d(ptr ? Data::getAndRef(ptr) : Q_NULLPTR), value(ptr)
              ^

              /home/shahriar/Qt5.6.0/5.6/gcc_64/include/QtCore/qsharedpointer_impl.h:705: error: cannot convert 'QStandardItem*' to 'QObject*' in initialization
              inline QWeakPointer(X *ptr, bool) : d(ptr ? Data::getAndRef(ptr) : Q_NULLPTR), value(ptr)
              ^

              and it points ti this line:
              inline QWeakPointer(X *ptr, bool) : d(ptr ? Data::getAndRef(ptr) : Q_NULLPTR), value(ptr)

              what is this?

              kshegunovK Offline
              kshegunovK Offline
              kshegunov
              Moderators
              wrote on last edited by kshegunov
              #6

              @shahriar25
              Hi,

              what is this?

              Well, it is me being stupid. The errors are because QStandardItem doesn't derive from QObject (which it shouldn't). Forget that code and look at my previous post (responding to SGaist) for the "explanation", sorry for misleading you!

              Read and abide by the Qt Code of Conduct

              1 Reply Last reply
              0
              • S Offline
                S Offline
                shahriar25
                wrote on last edited by
                #7

                Well @kshegunov
                this code prints Not Deleted!!! :

                QStandardItem *item = new QStandardItem("Row 1!!!");
                
                model.appendRow(item);
                model.clear();
                
                if (item)
                    cout<<"Not Deleted!!!"<<endl;
                else
                    cout<<"Deleted!!!"<<endl;
                

                So item doesn't get deleted;

                I have about ten models and each one of them take about 200mb ram so I Want to clear the old model before showing a new one . when I load and clear three models one after another gnome system monitor shows the app uses 1gb memory!!! (the sum of the memory of three models)

                kshegunovK 1 Reply Last reply
                0
                • S shahriar25

                  Well @kshegunov
                  this code prints Not Deleted!!! :

                  QStandardItem *item = new QStandardItem("Row 1!!!");
                  
                  model.appendRow(item);
                  model.clear();
                  
                  if (item)
                      cout<<"Not Deleted!!!"<<endl;
                  else
                      cout<<"Deleted!!!"<<endl;
                  

                  So item doesn't get deleted;

                  I have about ten models and each one of them take about 200mb ram so I Want to clear the old model before showing a new one . when I load and clear three models one after another gnome system monitor shows the app uses 1gb memory!!! (the sum of the memory of three models)

                  kshegunovK Offline
                  kshegunovK Offline
                  kshegunov
                  Moderators
                  wrote on last edited by kshegunov
                  #8

                  @shahriar25

                  So item doesn't get deleted

                  i can assure you it does - here. But in any case, what's your Qt version?

                  this code prints Not Deleted!!!

                  As expected. The difference between QPointer and raw pointer (which you're using in your last snippet) is that QPointer is set to NULL when the QObject is deleted. This is not the case for raw pointers. So even if the item is deleted your item variable will still point to the same memory address, thus this code will always print "Not Deleted".

                  Kind regards.

                  Read and abide by the Qt Code of Conduct

                  1 Reply Last reply
                  0
                  • S Offline
                    S Offline
                    shahriar25
                    wrote on last edited by shahriar25
                    #9

                    Well @kshegunov
                    Then have nothing to worry about and there is no memory leak. Thank you both @kshegunov & @SGaist.
                    I'm uisng Qt 5.6

                    1 Reply Last reply
                    0
                    • B Offline
                      B Offline
                      Bikram Shishodia
                      wrote on last edited by
                      #10

                      Try this:
                      Here I was adding 4 standardItem in one row starting from column 1.
                      The same I am deleting before clearing the Model.
                      m_qsimAlarmModel is my object of QStandardItemModel.

                      Below code is not tested, some change may required.

                      for (int i = 0; i<m_qsimAlarmModel->rowCount();i++)
                      {
                      QStandardItem *test = nullptr;
                      test = m_qsimAlarmModel->takeItem(i,1);
                      delete test;
                      test = nullptr;
                      test = m_qsimAlarmModel->takeItem(i,2);
                      delete test;
                      test = nullptr;
                      test = m_qsimAlarmModel->takeItem(i,3);
                      delete test;
                      test = nullptr;
                      test = m_qsimAlarmModel->takeItem(i,4);
                      delete test;
                      test = nullptr;

                          }
                      
                      1 Reply Last reply
                      0

                      • Login

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