我有一个带有QPushButton的QGraphicsScene,清除这个场景会使我的应用程序崩溃.有没有正确的方法来清除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();
}
Run Code Online (Sandbox Code Playgroud)
程序崩溃的原因是QGraphicsScene :: clear()方法在使用这些非常数据结构的方法调用中删除了QButton(及其关联的数据结构).然后,在clear()返回后,调用方法立即尝试访问现在删除的数据(因为它不希望在其例程中删除),然后发生崩溃.你的问题是一个重新入侵问题的例子.
避免绊倒鞋带的最简单方法是使您的信号/插槽连接成为QueuedConnection而不是AutoConnection:
QObject::connect(button, SIGNAL(clicked()), scene, SLOT(clear()), Qt::QueuedConnection);
Run Code Online (Sandbox Code Playgroud)
这样,只有在按钮的鼠标按下处理例程返回之后才会执行clear()方法调用,因此将从可以安全删除按钮的上下文中调用clear().