2016-12-13 10 views
0

次のコードがあります。それは、QGraphicsViewオブジェクトを作成する場面を設定し、シーンに追加されたQGraphicsWebViewオブジェクトが作成されます。10秒後QGraphicsViewオブジェクトを削除しようとするスロットが呼び出され中央ウィジェットであったQGraphicsViewオブジェクトを正しく削除するには?

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" 

。問題は、graphicsViewを削除しようとすると、約2秒後にプログラムがクラッシュすることです。バックトレースはゴミです。理論的にQGraphicsViewオブジェクトはその子を削除し、子はQGraphicsSceneオブジェクトです。シーンはQGraphicsWebViewオブジェクトである子を削除する必要があります。

プロセスをクラッシュせずにQGraphicsViewオブジェクトを正しく削除する方法はありますか?

これはQtの4.8

+0

中央ウィジェットの周りに余分なアクロバットを行うには理由がありません:あなたはもうそれを必要としないとき、単にウィジェットを削除します。 –

答えて

0

で、それが適切にクリーンアップしない理由を私は理解していないが、私はあなたのシーンのgraphicsView親をすることはないだろう。シーンに親を与える代わりに、ビューの後にdeleteWebViewスロットで削除するだけです。

0

私は再現できません。以下は、一貫してOS X上のQt 4.8.7にクラッシュせずに動作します:

#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" 
関連する問題