[Solved] Removing objects from QLayout; adding new ones.



  • Hi,

    I have a layout where I draw, when needed, a custom QWidget with some information about one of my object classes. When I click on another object, I would like to remove this custom QWidget, and draw on this layout another custom QWidget corresponding to the new clicked object.

    In order to remove and draw the new object, I've implemented this method, called when click signal is triggered:

    @
    void MainWindow::showBottomPanel(QWidget wid)
    {
    if (wid == 0) return;
    QLayout
    layout = ui->bottomLayoutMainPanel;
    if (layout == 0){ //Just some checks
    qDebug() << "No layout setted to frame. ";
    return;
    }
    //Clearing all elements in layout (manually).

    qDebug () << "Pointer to: " << wid;
    int i = 0;
    while (QLayoutItem* item = layout->itemAt(i)){
        if (item->widget()){
            layout->removeItem(item);
            // delete item; I DON'T DELETE MY OBJECT.
        }else i++;
    
    }
    layout->addWidget(wid);
    ui->bottomPanel->update();
    

    }
    @

    As you can see, I don't delete my custom widget object because if I reclick on the first object, I want to restore the QWidget and draw it again on the layout. So, I don't want to lose my object in memory.

    Problems: layout->removeItem(item); doesn't remove the item from layout. It continues stacking QWidgets again and again.

    How can I remove custom QWidgets object from a Layout, avoiding stacking, and saving the object in memory to redraw it again if needed?

    Thank you.


  • Lifetime Qt Champion

    Hi,

    Since you want to reuse your widgets, why not make use of "QStackedLayout":http://qt-project.org/doc/qt-4.8/qstackedlayout.html ? That would simplify the handling a lot

    Hope it helps



  • Thank you SGaist, for your fast reply.

    If I'm not wrong, QStakedLayout uses arrows to navigate between objects. This is not exactly what I want, but I can works if I can set manually the active widget by clicking the custom QGraphicObject in scene.

    Anyway, I found this other solution:
    @
    bool found = false;
    while (QLayoutItem* item = layout->itemAt(i)){
    if (item->widget()){
    QWidget* actual = item->widget();
    if (actual == wid){ //Wid is the only object that i want to see
    item->widget()->showFullScreen();
    found = true;
    }else{
    item->widget()->hide();
    }
    i++;
    }
    }
    if (!found){
    layout->addWidget(wid);
    wid->hide();
    wid->showFullScreen();
    }
    @

    wid* is the only object that I want to see. The others are hidden. My second question is: is it a good and clean solution? I have the impression that is a botched job.


  • Lifetime Qt Champion

    You're welcome !

    But you are wrong, QStackedLayout (like the name says) is a layout so nothing to navigate is shown. I think you are mixing it with, maybe, QTabWidget.

    This layout puts your widgets on top of another showing only the current, which, if I understood your question right, is what you try to accomplish



  • That's it! I was mixing with QTabWidget, sorry. I'm just too new in Qt. Tomorrow I'm trying your suggestion, but it seems just that I need.

    Just to know, anyway, is it a clean solution showing and hidding as I show at code above?

    Thank you again, SGaist.


  • Lifetime Qt Champion

    You're welcome.

    The code in itself doesn't look bad, but I never tried to call showFullScreen on a "layouted" widget so I don't know how it will react.



  • What about using just "show()"? It's a bit strange there is no methods like QWidget::clear() or something like that.


  • Lifetime Qt Champion

    The opposite of show() is hide(). But really, go with the QStackedLayout, more intuitive and it handle everything for you.



  • Thank you! Solved!


Log in to reply
 

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