Deleting data from a QScrollArea



  • Hello!

    I am having some trouble removing data from a QScrollArea. When I load data into my GUI, I can school and everything is fine. When I load another set of data, however, my GUI adjusts it's scroll area to match that of the new file but doesn't get rid of the old data. It just lays the new data on top of the old data, creating a neat effect but unwanted.

    Here is my code:

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);
    
    scrollArea = new QScrollArea();
    scrollArea->setBackgroundRole(QPalette::Light);
    scrollArea->setWidgetResizable(true);
    
    mainVbox = new QVBoxLayout();
    
    myWidget = new QWidget();
    myWidget->setLayout(mainVbox);
    
    scrollArea->setWidget(myWidget);
    
    setCentralWidget(scrollArea);
    }
    

    So I create my QScrollArea, change some of it's attributes.
    Next I create a widget to hold my main layout.
    Then I set the widget of scrollArea to myWidget.
    Lastly, I set the central widget to scrollArea.

    What I add to the mainLayout is another layout that contains three widgets. And I add a LOT of these layouts to the main layout. Here is that code with the code I thought would delete the old layouts

    ...
    ...
    QLayoutItem* child;
    while((child = myWidget->layout()->layout()->takeAt(0)) != NULL)
    {
        delete child->layout()->widget();   //This doesn't work but it doesn't break anything...
    }
    
    
    for(int counter = 0; counter < orderQ.size(); counter++)
    {
        subHbox = new QHboxLayout;
        
        if(orderQ.at(counter) == 0)
            {
                Qlabel *label = new QLabel();
                ...
                ...
                mainVbox->addLayout(subHbox);
            }
        else if(...)
        { 
            ...
            mainVbox->addLayout(subHbox);
            ...
        }
    

    Any help or ideas would be greatly appreciated.

    Thank you!!


  • Qt Champions 2016

    Hi
    I was wondering why you cannot just delete
    myWidget as that would/should delete all childs also.
    Then make new "myWidget" and fill it again.



  • Thank you for your reply!

    I tried deleting myWidget and no matter what I did, it crashed every time. But that got me thinking of other ways to approach this. So I did some more thinking and searching, and found in the docs this.

    I tried

    QList<QLayout *> allSubLayouts = mainVbox->findChildren<QLayout *>();
    if(!allSubLayouts.empty())
    {
        int size = allSubLayouts.size();
        for(int i = 0; i < size; i++)
        {
           delete allSubLayouts.at(i);
        }
    }
    

    that produced no results but maybe just deleting the layout only removes the layout. So I tried deleting the widgets in those layouts before deleting the layouts.

    if(!allSubLayouts.empty())
        {
        int size = allSubLayouts.size();
        QLayoutItem *child;
    
        qDebug() << "***************The layout list was not empty" ;
        for(int i = 0; i < size; i++)
        {
            while((child = allSubLayouts.at(i)->takeAt(0)) != 0)
            {
                qDebug() << "deleting CHILD " << child;
                delete child;
            }
            qDebug() << "deleting layout " << i << " that has memory address " << allSubLayouts.at(i);
            delete allSubLayouts.at(i);
        }
        mainVbox->update();
        myWidget->update();
    }
    

    As you can see I also tried updating the main layout as well as the widget to no avail. The debug printout says that it is making it into the loop and accessing the correct number of widgets and layouts. I'm just not sure of what to do right now.


  • Qt Champions 2016

    @mar0029 said:
    ok, its hard to visualize what u put in to what ;)

    Have you tried making a brand version and simply replace it ?
    scrollArea->setWidget(myWidgetNo2);



  • @mrjj I made a diagram as to what I've created. I'm creating a lot of the QHBoxLayouts within QVBoxLayout.


  • Qt Champions 2016

    @mar0029
    That is super.
    So its the "red" ones you are trying to replace?

    Also, can u just replace Widget holding all the reds,?
    or you do u need to keep some of them?



  • @mrjj Thank you! I used a ruler and everything!

    I would like to keep everything up to the red a.k.a. my QVBoxLayout
    What happens to all of the QHboxLayout and all the widgets within those Layouts, I don't care.


  • Qt Champions 2016

    Hmm.
    Ok. I was kinda planning
    to just create new widget with a boxlayout and call
    setWidget on ScrollArea.
    But u say this crashes?


  • Qt Champions 2016

    Hi again
    i made same layout in designer
    I kill them this way

    
    void MainWindow::on_btremove_released() {
    
      QList<QWidget*> allSubLayouts = ui->innerwidget->findChildren<QWidget*>(QString(), Qt::FindDirectChildrenOnly);
      int size = allSubLayouts.size();
      // take all out
      while (( ui->innerwidget->layout()->takeAt(0)) != 0)
        // killem
        for(int i = 0; i < size; i++) {
          qDebug() << allSubLayouts[i]->metaObject()->className();
          delete allSubLayouts[i];
    
        }
    
    
    }
    
    

    U can check your self.
    https://www.dropbox.com/s/auivviiv8tv7jfw/myscroll.zip?dl=0
    should be the same you want if i read ur fine drawing correct :)
    Note the Qt::FindDirectChildrenOnly flag!



  • @mrjj
    I don't want to delete my QWidget because I would have to dynamically create a new one each time I loaded a new file and I really don't want to deal with that.

    I'm making some progress with this:

        while((child = mainVbox->layout()->takeAt(0)) != 0)
            {
            delete child;
            }
    

    but in the documentation it says that when I delete a layout, I have to delete the widgets separately.
    So I'm trying to make a list of the widgets found within the sublayout and then delete from there but it's not working.


  • Qt Champions 2016

    Did u try the sample?
    It leaves the QWidget and layout but kills all it members.



  • @mrjj oh my where did you find that flag? How did you know you could do ui->innerWidget->findChildren<QWidget*>(String(), Qt::FindDirectChildrenOnly); ??



  • @mrjj Thank you for your help. I am unable to get it to work right now but I can see this achieving the goal. I will come back to it later today/tomorrow.

    Thanks again!


  • Qt Champions 2016

    Hi
    In the documentation for findChildren. I went looking as your
    drawing made it very clear what u wanted. (kill all inner widgets)

    So If you do it for your Widget (myWidget), it should do the same.
    ( i hope :)

    you are welcome. I hope u get it to work.



  • @mrjj
    So here is what I've ended up doing.

    I had been able to get a QList of the layouts in the main layout like so

     QList<QLayout *> allSubLayouts = mainVbox->findChildren<QLayout *>();
    

    So I checked if that list was empty or not, basically seeing if it was the first time to use the program.

    if(!allSubLayouts.empty())
    {
    
        int size = allSubLayouts.size();
        for(int i = 0; i < size; i ++)
        {
            qDebug() << "this is what is at allSublayouts.at("<<i<<") " << allSubLayouts.at(i);
    
    
            for(int j = 0; j < allSubLayouts.at(i)->count(); ++j)
            {
                QWidget *w = allSubLayouts.at(i)->itemAt(j)->widget();
                if(w != NULL)
                {
                    w->setVisible(false);
                }
            }
        }
    }
    

    Since I knew that there were layouts available, instead of using findChildren() I used allSubLayouts.at(i)->*itemAt*(j)->*widget*();

    While this solves my problem of widgets and layouts overlapping in MainWindow, I don't know if it will cause a memory leak or will use up too much memory, since I'm not deleting any widgets/layouts.


  • Qt Champions 2016

    Hi

    "allSubLayouts.at(i)->*itemAt*(j)->*widget*();"
    

    made my brain hurt :)
    Well since u are not deleting any widgets, u will use more and more memory,
    but since they are still owned by layout, it will be free when application ends.


Log in to reply
 

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