PDA

View Full Version : How to correctly delete a QDialog created via 'new'?



eyeofhell
31st May 2010, 06:03
Hello.

I have an app that can have a number of info windows. I create them using:

CInfoWnd* wnd = new CInfoWnd( main_wnd );
wnd->show();

But since they are automatically deleted only after they parent object is deleted (main window), they remain in meory even after user closes them. Si, if user constantly opens and closes info windows, memory is constantly leaking. What is a preffered way in Qt to dispose windows that are created via 'new'?

Lykurg
31st May 2010, 06:57
You can reuse the window instead creating a new one. If you what delete it use
delete wnd;
//or
wnd.deleteLater();. It does not matter. You also can use the window attribute deleteOnClose.

Lesiok
31st May 2010, 06:59
CInfoWnd* wnd = new CInfoWnd( main_wnd );
wnd->setAttribute( Qt::WA_DeleteOnClose, true );
wnd->show();Dialog will be deleted after close.

eyeofhell
31st May 2010, 08:00
Dialog will be deleted after close.

Unfortunately, no. At last for Qt 4.6. I have tested this by opening and closing a dialog - the memory is constantly incrementing by 500kb per dialog :(.

aamer4yu
31st May 2010, 08:12
Can you share the code ??
Without it, hard to say..

eyeofhell
31st May 2010, 09:07
I have checked all mentioned ways. Overriding eventClose() and issuing deleteLater() in it works like a charm.
deleteOnClose attribute works for empty QDialog, but after adding child widgets, signals and slots app crash with access violation on internal delete upon dialog close. Maybe this flag has some additional constraits / conditions i'm not aware about.

high_flyer
31st May 2010, 09:26
but after adding child widgets, signals and slots app crash with access violation on internal delete upon dialog close.
Any QObject which you allocate on the heap, and do not parent, you have to delete your self.
This could cause such an error, when some objects are deleted, but not all, and/or, when the deletion is not in the correct order, and/or when you have parented the objects, and still try to delete them your self after they have been deleted by the parent.

Zyl
19th November 2010, 23:20
*Moderate dig*

The problem with calling deleteLater() on the QDialog or deleting it after exec() is, that for a short moment the dialog will freeze and then disappear when clicking a button that causes the function to return, instead of just disappearing normally (or fade-away animation under Vista/W7). That simply is not nice.

I have made a dirty workaround which does not take the lag from the main event loop, but at least lets the animation play smoothly:

dialogdestroyer.h:

#ifndef DIALOGDESTROYER_H
#define DIALOGDESTROYER_H

#include <QThread>
#include <QDialog>

class DialogDestroyer : public QThread
{
public:
DialogDestroyer();

void DelayedDestruction(QDialog* lDialog);

private:
void run();

QDialog* mDialog;
};

#endif // DIALOGDESTROYER_H

dialogdestroyer.cpp:

#include <QTimer>

#include "dialogdestroyer.h"


DialogDestroyer::DialogDestroyer() {

}

void DialogDestroyer::DelayedDestruction(QDialog* lDialog) {

mDialog = lDialog;

this->start();

}

void DialogDestroyer::run() {

msleep(300);

mDialog->deleteLater();
this->deleteLater();
}

Somewhere:

void MainWindow::on_actionOpen_triggered() {

QFileDialog* lDiag = new QFileDialog(this, QString("Select file to open"),
QString("D:\\"), QString("Text files (*.txt)"));

int lResult = lDiag->exec();

if(lResult != QDialog::Rejected) {
// Do stuff...
}

(new DialogDestroyer())->DelayedDestruction(lDiag);
}

There should be a better way/implementation, in my honest opinion.