Removing a widget from a QTableView

I have a delete button (QPushButton) in the last column of each row of my table view. I create these buttons and directly configure them. Since I allocate memory dynamically, I want to free this memory, but I did not store pointers to these buttons anywhere, so I try to get the widget while cleaning and deleting them.

SDelegate* myDelegate;
myDelegate = new SDelegate();
STableModel* model = new STableModel(1, 7, this);
myWindow->tableView->setModel(model);
myWindow->tableView->setItemDelegate(myDelegate);
for(int i = 0; i < no_of_rows; ++i) {
    QPushButton* deleteButton = new QPushButton();
    myWindow->tableView->setIndexWidget(model->index(i, 6), deleteButton);
}
exec();

// Cleanup
for(int i = 0; i < no_of_rows; ++i) {
    // code works fine on removing this particular section
    QWidget* widget = myWindow->tableView->indexWidget(model->index(i, 6));
    if (widget)
        delete widget;
}
delete model;
delete myDelegate;

I get a failure in qt5cored.dll (unhandled exception) and the application crashes in qcoreapplication.h with the following code:

#ifndef QT_NO_QOBJECT
inline bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event)
{  if (event) event->spont = false; return self ? self->notifyInternal(receiver, event) : false; }

During debugging, there is no problem removing these widgets, but after that the code crashes at some other point. I am using QTableView and a custom class for a model that has inherited QAbstractTableModel.

+2
source share
2

Qt, : - , setModel(nullptr) , visualRow != -1 qtableview.cpp:1625 ( Qt 5.6.0). , , - .

, . , , .

, , . , , , . ? ? ?

, . . : , , , . , , , .

, , , , , . Qt: , destroyed. Qt 4 .

// https://github.com/KubaO/stackoverflown/tree/master/questions/model-indexwidget-del-38796375
#include <QtWidgets>

int main(int argc, char ** argv) {
   QApplication app{argc, argv};
   QSet<QObject*> live;
   {
      QDialog dialog;
      QVBoxLayout layout{&dialog};
      QTableView view;
      QPushButton clear{"Clear"};
      layout.addWidget(&view);
      layout.addWidget(&clear);

      QScopedPointer<QStringListModel> model{new QStringListModel{&dialog}};
      model->setStringList(QStringList{"a", "b", "c"});
      view.setModel(model.data());
      for (int i = 0; i < model->rowCount(); ++i) {
         auto deleteButton = new QPushButton;
         view.setIndexWidget(model->index(i), deleteButton);
         live.insert(deleteButton);
         QObject::connect(deleteButton, &QObject::destroyed, [&](QObject* obj) {
            live.remove(obj); });
      }
      QObject::connect(&clear, &QPushButton::clicked, [&]{ model.reset(); });
      dialog.exec();
      Q_ASSERT(model || live.isEmpty());
   }
   Q_ASSERT(live.isEmpty());
}
+1

QObject:: deleteLater(), , QObjects/QWidgets.

-1

Source: https://habr.com/ru/post/1650667/


All Articles