www
www

Reputation: 596

Removing itself from layout using context menu

I am using FlowLayout example of qt.

I added a context menu for all items in FlowLayout to enable renaming and removing. Renaming works, but whenever I call Remove, I receive a Segmentation Error.

Here is the removeSlot call:

  QAction *removeAction = new QAction(tr("Remove"), this);
  connect(removeAction, SIGNAL(triggered()), this, SLOT(removeSlot()));
  Menu->addAction(removeAction);

And emitting signal:

void FlowLayoutWidget::removeSlot()
{
  emit removeMe(m_ownId);
}

FlowWindow.cpp catches the signal and executes the following code:

void FlowWindow::removeItemAt(int _index)
{

  while(QLayoutItem* item = flowLayout->itemAt(_index))
  {
      QWidget* widget = item->widget();
      flowLayout->removeWidget(widget);
      delete widget;
      break;

  }
}

Whenever this function is called, I receive a segmentation error. How can I solve this?

Upvotes: 0

Views: 314

Answers (1)

tmpearce
tmpearce

Reputation: 12683

You're calling delete on an object from within a slot triggered by that object. That can sometimes be problematic, in ways that are not always obvious to predict. I suspect it may be causing your problem in this case. Qt provides the method QObject::deleteLater() which deals with this by scheduling the object for deletion after control returns to the event loop.

void FlowWindow::removeItemAt(int _index)
{

  while(QLayoutItem* item = flowLayout->itemAt(_index))
  {
      QWidget* widget = item->widget();
      flowLayout->removeWidget(widget);
      //delete widget; avoid this
      widget.deleteLater(); //try this instead
      break;

  }
}

See this question/answer for some more info.

Also, I will note that since you're deleting (or scheduling for deletion) the object, you shouldn't need to explicitly call flowLayout->removeWidget(widget) - it will be automatically taken care of when the object is destroyed.

Upvotes: 1

Related Questions