1

I am using a QTreeWidget and setting a widget for the QTreeWidgetItem in the QTreeWidget. It is working fine but when I do the same for second time, the application is crashing.

The below is working fine.

QTreeWidget* treewidget = new QTreeWidget();
QTreeWidgetItem* item0 = new QTreeWidgetItem((QTreeWidget*)0, QStringList(QString("item0")));
treewidget->insertTopLevelItem(0,item0);
QSlider* slider0 = new QSlider();
treewidget->setItemWidget(item0, 0, slider0);

But if I add the last line once again, it is crashing when running the application.

The below is crashing.

QTreeWidget* treewidget = new QTreeWidget();
QTreeWidgetItem* item0 = new QTreeWidgetItem((QTreeWidget*)0, QStringList(QString("item0")));
treewidget->insertTopLevelItem(0,item0);
QSlider* slider0 = new QSlider();
treewidget->setItemWidget(item0, 0, slider0);
treewidget->setItemWidget(item0, 0, slider0);       // Intentionally added to simulate the issue

The above is an example to show the issue, but in my application, based on some events, I delete the tree widget items and add it later. When I set the item widget (after adding the items later), I am getting the crash.

I could not figure out why. Any ideas? FYI, I am using Qt 5.3.2 MSVC 2010, 32 bit.

demonplus
  • 5,613
  • 12
  • 49
  • 68
Sankar
  • 41
  • 1
  • 4

2 Answers2

1
treewidget->setItemWidget(item0, 0, slider0);
treewidget->setItemWidget(item0, 0, slider0);// Intentionally added to simulate the issue

I look at Qt code (4.x):

void QTreeWidget::setItemWidget(QTreeWidgetItem *item, int column, QWidget *widget)
{
    Q_D(QTreeWidget);
    QAbstractItemView::setIndexWidget(d->index(item, column), widget);
}

and QAbstractItemView::setIndexWidget:

void QAbstractItemView::setIndexWidget(const QModelIndex &index, QWidget *widget)
{
    Q_D(QAbstractItemView);
    if (!d->isIndexValid(index))
        return;
    if (QWidget *oldWidget = indexWidget(index)) {
        d->persistent.remove(oldWidget);
        d->removeEditor(oldWidget);
        oldWidget->deleteLater();
    }

so if you add slider0 two times, then at first call it was added, at seconds call Qt call for it deleteLater, and then added it, are sure that this is what you want?

fghj
  • 8,898
  • 4
  • 28
  • 56
0

You have to set correct parent in the constructor of QTreeWidgetItem. Try this:

QTreeWidgetItem* item0 = new QTreeWidgetItem(treewidget);

Also it is important to understand who is owner of the slider0 after calling of setItemWidget(): the owner is your table, so 1) you don't need to delete this object; 2) the object will be deleted if you call setItemWidget for the same cell again. So, double call of treewidget->setItemWidget(item0, 0, slider0); seems very strange (second time you are setting the deleted object into that cell).

Ilya
  • 4,583
  • 4
  • 26
  • 51
  • @Sankar, ok, but it is important to set correct parent any way. I've extended my answer (see details in the user1034749's answer) – Ilya Nov 10 '15 at 10:18
  • @llya, actually I am trying to implement a property window which contains a tree widget. Each tree widget item contains a widget (set using setItemWidget() ). The property window shows property of object i am selecting. Let's say the tree widget is showing the properties of Object A, I am selecting Object B and when I select the Object A again, I am removing the items in the tree widget (which actually belongs to Object B) and adding the Object A items again. When i do this, it is not having the item widget i set initially. So i am setting the item widget again, which is causing the crash. – Sankar Nov 10 '15 at 10:41
  • What does "which actually belongs to Object B" means? If it means "which actually corresponds to" it is ok (i.e. if you create new widgets before calling of `setItemWidget`). But if you are using pointers on that objects (parts of Object B) as arguments of `setItemWidget` it is wrong, because in this case you are losing ownership (and this is the reason of the crash). – Ilya Nov 10 '15 at 11:18
  • No i am not using pointers of Object B as arguments for 'setItemWidget'. I was using the same widget as argument for 'setItemWidget' two times. As you said, it is deleted when i call 'setItemWidget' second time. It could be a reason for the crash. Anyway, i have to look fir different approach for my use case. Thanks! – Sankar Nov 10 '15 at 11:39