[Solved] Destruct QWizard after wizard finished
-
I want to destruct a QWizard after the wizard is finished. The source code I wrote looks like this
@
MainWindow::MainWindow(QWidget *parent) :
QDialog(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}void MainWindow::accept()
{
wizard = new MainWizard(this);
connect(wizard, SIGNAL(finished(int)), this, SLOT(wizardClosedHandler(int)));
wizard->show();
}MainWindow::~MainWindow()
{
delete ui;
}void MainWindow::wizardClosedHandler(int ret)
{
delete wizard;
return;
}
@The wizard is deleted in the slot function wizardClosedHandler(int) which is connected with signal finished(int). It work well in debug mode. But while I run it not in debug mode, it cause some error. I tried to find out which line was the cause. It points to the line "delete wizard" is the root cause.
I don't know why it works in the debug mode. Is there any better way to find out where the problem is?
I want my wizard destroyed after QWizard was finished (it emit signal finished(int)). Is this the correct way to implement it? Thank you in advance.
-
The problem is, that you are deleting an object that is still being run. That is asking for trouble.
What happens if that the QWizard code does an emit for the finished signal. Recognize that at this point, the code point is inside a method of the QWizard code. Something else might be after that emit, you don't know. The emit statement takes the code path outside of QWizard if you connect to it. In your case, it goes to the wizardClosedHandler. There, the wizard then gets deleted. After the slots that were connected to the signal have finished processing, control returns to the point just after the emit... However, that object was just deleted. That results in undefined behaviour.
So: don't delete objects in response to signals from those objects. Note that this might be harder to do than you think. In your case, the connection is clear, but there may be cases where a signal triggers a whole cascade of other signals and slots that may, in the end, result of the deletion of the object that send the signal that triggered the whole cascade in the first place. That is very hard to debug. You can avoid it in your own code, but it takes disipline and some tricks to do so.
In your case, the solution is simple though: replace your connect statement with this:
@
connect(wizard, SIGNAL(finished(int)), wizard, SLOT(deleteLater()));
@You can remove your void MainWindow::wizardClosedHandler(int ret) method.