Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Removing widgets from layout without destroying them

    General and Desktop
    4
    7
    6467
    Loading More Posts
    • 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
      Aerius last edited by

      I'm using a QTabWidget to display various data. This data is contained in classes that are derived from QWidget. As I have several versions of the same data ( for several different years ), I want to be able to swap the displayed version. I use a QComboBox to call a method that does that for me. On construction, I create my data and put one of the widgets into my tabWidget:

      @
      // during construction
      MyData *firstData, *secondData; // MyData is a custom class, derived from another virtual custom class that derives from QWidget
      firstData = new MyData();
      secondData = new MyData();
      // do some parameterisation
      // ...
      _allData->append(firstData); // _allData is a QList that stores all different versions of my data
      _allData->append(secondData);

      _ui->dataLayout->addWidget( _allData->at(_allData->count() -2)); // dataLayout is the layout of one of the tabs of my tabWidget. This complicated way of adding the correct widget has it's background. I know I could simply append firstData, but I need to be flexible if I want to have more versions of my data.

      @

      So far so good. This works without a problem for all different tabs I use.

      I then have a comboBox that calls a slot named 'changeYear' on the signal 'currentIndexChanged(QString)'. This slot looks like this:

      @
      void MyClass:changeYear(QString year) {

      int displayYear = year.toInt()
      
      _ui->dataLayout->takeAt(0);    // I would expect this to remove the QLayoutItem that encapsulates my Data from the Layout.
      //_ui->dataLayout->update();     this doesn't work either - makes no difference.
      
      // add the correct widget
      for ( int i = 0; i < _allData->count(); ++i ) {
          if ( _allData->at(i)->year() == displayYear ) {        // Data->year() returns an int I use to identify which version of my Data this is
              _ui->dataLayout->addWidget(_allData->at(i));
              break;
          }
      }
      

      }

      @

      The slot gets called correctly and the for-loop correctly identifies the new data I want to add to my layout. However, takeAt() doesn't remove the old widget. This leads to having both Widgets in my layout at once, which, of course, doesn't quite work.

      I know I can do:
      @

      QLayoutItem *thisItem = _ui->dataLayout->takeAt(0);
      delete thisItem->widget();

      @

      to get rid of it. That, however, doesn't help me, as I don't want to destroy my data. This is not up for discussion.
      However, whatever I tried to only remove the Widget from my layout, it didn't work. I could simply add all my Data Widgets to my layout and hide() and show() accordingly, but this causes extra headache for all my signals and slots I'd have to take care of. Also, why would I want to do that in the first place?

      Any chance I can just remove my Widget from the layout without having to destroy it?

      1 Reply Last reply Reply Quote 0
      • C
        cincirin last edited by

        "QLayout::removeWidget":http://qt-project.org/doc/qt-4.8/qlayout.html#removeWidget

        bq. Removes the widget from the layout.

        1 Reply Last reply Reply Quote 0
        • A
          Aerius last edited by

          Yeah well, I should've said that I tried removeWidget and removeItem as well to no avail. The widget I want to remove simply still shows.

          1 Reply Last reply Reply Quote 0
          • C
            cincirin last edited by

            Yes, but the doc say:

            bq. After this call, it is the caller's responsibility to give the widget a reasonable geometry

            So ... just hide it, or give it a reasonable geometry if you want it to be still visible :-)

            1 Reply Last reply Reply Quote 0
            • A
              Aerius last edited by

              Well, I'd have expected a widget that is not part of any layout wouldn't be displayed anyways, but I guess that's my fault then.

              Thank you for pointing out my error here.

              1 Reply Last reply Reply Quote 0
              • B
                b1gsnak3 last edited by

                you could also try using "QStackedLayout":http://qt-project.org/doc/qt-4.8/qstackedlayout.html

                1 Reply Last reply Reply Quote 0
                • U
                  utcenter last edited by

                  I've commonly used this approach to create simple list-like UI:

                  @void QtPropertyGenerator::addProperty() {
                  Widget p = new Widget(this);
                  ui->pLayout->addWidget(p);
                  properties.append(p);
                  connect(p, SIGNAL(deleteMe(Widget
                  )), this, SLOT(deleteProperty(Widget*)));
                  }

                  void QtPropertyGenerator::deleteProperty(Widget *p) {
                  ui->pLayout->removeWidget(p);
                  properties.removeOne(p);
                  p->deleteLater();
                  }@

                  Just remove the deleteLater() line and remember to hide the widget because it will show without the layout.

                  1 Reply Last reply Reply Quote 0
                  • First post
                    Last post