c++qtqt4

Clearing a Layout in Qt


I'm creating an application in Qt that allows users to drag around various "modules" in a QGraphicsView. Whenever one of these modules is selected, it emits a signal which is then picked up by a "ConfigurationWidget" which is a side-panel which should display all of the relevant parameters of the selected module:

class ConfigurationWidget : public QWidget
{
  Q_OBJECT

  public:
    ConfigurationWidget(QWidget *parent) : QWidget(parent) {}  

  public slots:
    void moduleSelected(Module* m)
    {
      if(layout())
      { 
        while (itsLayout->count()>0) 
        { 
          delete itsLayout->takeAt(0); 
        }
      }
      delete layout();

      itsLayout = new QFormLayout(this);
      itsLayout->addRow(QString(tr("Type:")),     new QLabel(m->name()));
      itsLayout->addRow(QString(tr("Instance:")), new QLabel(m->instanceID()));
      // ... Display a whole bunch of other fields that depends on the module
    }
};

The problem is that the ConfigurationWidget never actually gets cleared when a module is selected. The new fields are just drawn over the old ones. I've tried various combinations of hide() and show(), invalidate(), update(), etc. to no avail.

What's the correct way to make a widget that can change its fields like this on the fly?


Solution

  • It looks like the best way to do this is to use a QStackedLayout, as hinted at by armonge:

    void ConfigurationWidget::moduleSelectedSlot(Module* m)
    {
      QStackedLayout *stackedLayout = qobject_cast<QStackedLayout*>(layout());
    
      QWidget *layoutWidget = new QWidget(this);
      QFormLayout *formLayout = new QFormLayout(layoutWidget);
      formLayout->addRow(QString(tr("Type:")),     new QLabel(m->name()));
      formLayout->addRow(QString(tr("Instance:")), new QLabel(m->instanceID()));
      // ... Display a whole bunch of other fields that depends on the module
    
      delete stackedLayout->currentWidget();
      stackedLayout->addWidget(layoutWidget);
      stackedLayout->setCurrentWidget(layoutWidget);
    }