Есть следующий код. Он создает объект QGraphicsView, устанавливает сцену, а затем создается объект QGraphicsWebView, который добавляется к сцене:
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 секунд вызывается слот, который пытается удалить объект QGraphicsView. Проблема в том, что когда я пытаюсь удалить graphicsView, программа вылетает примерно через 2 секунды. Обратные следы мусора. Теоретически объект QGraphicsView должен удалить своих потомков, а дочерний объект является объектом QGraphicsScene. Сцена должна удалить своего потомка, который является объектом QGraphicsWebView.
Как правильно удалить объект QGraphicsView без сбоев процесса?
Это Qt 4.8
Я не понимаю, почему он не очищается должным образом, но я бы не стал делать graphicsView родителем вашей сцены. Вместо того, чтобы предоставить сцене родительский объект, просто удалите его в своем слоте deleteWebView после представления.
Я не могу воспроизвести. Следующее работает согласованно и без сбоев на Qt 4.8.7 на OS X:
#include <QtGui>
#include <QGraphicsWebView>
#include <QGLWidget>
class Window : public QMainWindow {
Q_OBJECT
QWidget central;
QVBoxLayout layout{¢ral};
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(¢ral);
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"