在QGraphicsScene中清除小部件:崩溃

4

我有一个QGraphicsScene,里面有一个QPushButton,但是清除这个场景会导致我的应用程序崩溃。是否有正确的方法可以清除包含QWidget的场景?

当单击按钮时,以下代码会导致崩溃:

#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsProxyWidget>
#include <QPushButton>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    QGraphicsScene *scene = new QGraphicsScene();

    QGraphicsView *view = new QGraphicsView();
    view->setScene(scene);
    view->show();

    QPushButton *button = new QPushButton("button");
    QObject::connect(button, SIGNAL(clicked()), scene, SLOT(clear()));

    QGraphicsProxyWidget *proxy = scene->addWidget(button);

    return app.exec();
}
1个回答

8
你的程序崩溃的原因是 QGraphicsScene::clear() 方法在使用这些数据结构的方法调用的中间删除了 QButton(和其关联的数据结构)。然后,在 clear() 返回后,调用方法尝试访问现在已被删除的数据(因为它没有预计会在其例程的中途被删除),因此发生崩溃。你的问题是“可重入性问题”的一个例子。
避免这种情况最简单的方法是将你的信号/槽连接设置为 QueuedConnection 而不是 AutoConnection:
 QObject::connect(button, SIGNAL(clicked()), scene, SLOT(clear()), Qt::QueuedConnection);

这样一来,clear()方法的调用就不会在按钮的鼠标按下处理程序返回之前执行,因此clear()将在一个安全删除按钮的上下文中被调用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接