0

There is following code. It creates QGraphicsView object, sets a scene and then there is created a QGraphicsWebView object which is added to the scene:

QGraphicsWebView* graphicsWebView;
QGraphicsScene* graphicsScene;
QGraphicsView* graphicsView;
QMainWindow* mainWindow;

class Deleter : public QObject
{
    Q_OBJECT
public slots:
    void deleteWebView()
    {
        mainWindow->hide();
        mainWindow->centralWidget()->setParent(0);
        mainWindow->setCentralWidget(new QWidget());
        delete graphicsView; // <-- crashes about 2 seconds after that
    }
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    mainWindow = new QMainWindow;
    graphicsView = new QGraphicsView;
    graphicsScene = new QGraphicsScene(graphicsView);
    graphicsView->setScene(graphicsScene);
    graphicsWebView = new QGraphicsWebView;
    graphicsWebView->setUrl(QUrl("http://www.google.com"));
    graphicsView->scene()->addItem(graphicsWebView);
    graphicsView->setViewport(new QGLWidget());
    graphicsView->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
    mainWindow->setAttribute(Qt::WA_TranslucentBackground);
    mainWindow->setCentralWidget(graphicsView);
    mainWindow->show();
    Deleter d;
    QTimer::singleShot(10000, &d, SLOT(deleteWebView()));
    return app.exec();
}

#include "main.moc"

10 seconds later there is invoked a slot which tries to delete QGraphicsView object. The problem is that when I try to delete graphicsView, the program crashes after about 2 seconds. The backtraces are garbage. Theoretically QGraphicsView object should remove its children and the child is QGraphicsScene object. The scene should remove its child which is QGraphicsWebView object.

How to correctly delete QGraphicsView object without crashing the process?

This is Qt 4.8

Ciomco
  • 33
  • 4

2 Answers2

0

I don't understand why it doesn't clean up properly, but I would not make graphicsView a parent of your scene. Instead of giving the scene a parent, just delete it in your deleteWebView slot after the view.

goug
  • 2,294
  • 1
  • 11
  • 15
0

I can't reproduce. The following works consistently and without crashes on Qt 4.8.7 on OS X:

#include <QtGui>
#include <QGraphicsWebView>
#include <QGLWidget>

class Window : public QMainWindow {
   Q_OBJECT
   QWidget central;
   QVBoxLayout layout{&central};
   QPointer<QGraphicsView> view;
   QPushButton button{"Toggle View"};
   Q_SLOT void toggle() {
      if (!view) {
         view = new QGraphicsView;
         auto scene = new QGraphicsScene(view);
         auto webView = new QGraphicsWebView;
         webView->setUrl(QUrl("http://www.google.com"));
         scene->addItem(webView);
         view->setScene(scene);
         view->setViewport(new QGLWidget);
         view->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
         layout.addWidget(view);
      } else {
         delete view;
         view = nullptr;
      }
   }
public:
   Window() {
      layout.addWidget(&button);
      layout.addStretch(1);
      setAttribute(Qt::WA_TranslucentBackground);
      setCentralWidget(&central);
      connect(&button, SIGNAL(clicked(bool)), SLOT(toggle()));
   }
};

int main(int argc, char *argv[])
{
   QApplication app(argc, argv);
   Window w;
   w.show();
   return app.exec();
}

#include "main.moc"
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313