有以下代码。它创建了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
答案 0 :(得分:0)
我不明白为什么它没有正确清理,但我不会让graphicsView成为场景的父级。而不是给场景一个父级,只需在视图后的deleteWebView插槽中删除它。
答案 1 :(得分:0)
我无法重现。以下工作在OS X上的Qt 4.8.7上一致且没有崩溃:
#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"