Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt Modeless Dialog Destruction

Tags:

qt

qt4

From what I understand to make dialog Modeless you have to allocate it on the heap. By Doing something like this:

MyDialog* dlg = new MyDialog(this);
dlg->show();
dlg->raise();

Since exec() ignores Modal Property. However now there is a memory leak since nothing deallocates memory pointed to by dlg pointer until the application is closed. I found one solution here http://tinf2.vub.ac.be/~dvermeir/manuals/KDE20Development-html/ch08lev1sec3.html#ch08list09 at the end of the page and was wondering whether there was a less cumbersome way having Modeless dialog.

like image 490
Nickolay Kondratyev Avatar asked Aug 15 '11 18:08

Nickolay Kondratyev


3 Answers

You can use the attribute Qt::WA_DeleteOnClose to destroy the window when it is closed/hidden, and QWeakPointer (or QPointer) with a static variable to track the existence of the window inside the slot/function which opens it:

void MyWindow::openDialog() {    
    static QWeakPointer<MyDialog> dlg_;
    if (!dlg_)
        dlg_ = new MyDialog(this);

    MyDialog *dlg = dlg_.data();
    dlg->setAttribute(Qt::WA_DeleteOnClose);
    dlg->show();
    dlg->raise();
    dlg->activateWindow();
}
like image 82
alexisdm Avatar answered Nov 11 '22 23:11

alexisdm


I'd schedule it for deletion at the time it's work is finished by using deleteLater:

void MyDialog::MyDialog(QWidget *parent) {
    // ...
    connect(this, SIGNAL(finished(int)), SLOT(deleteLater)));
}

This approach will preclude you from examining it after the finished signal has been emitted (unless you can guarantee that any accesses happen before everything gets back to the event loop when the deletion is actually performed).

like image 44
Kaleb Pederson Avatar answered Nov 11 '22 23:11

Kaleb Pederson


Personally, I would choose between either using

dlg->setAttribute(Qt::WA_DeleteOnClose);

or making the dialog a -dynamically allocated- member i.e. creating it only once:

// constructor
  : dialog_(0)

// member function
{
  if (! dialog_)
    dialog_ = new MyDialog(this);

  dialog_->show();
  dialog_->raise();
}

This way the dialog is deleted when the parent dies, and only needs to be constructed once.

like image 39
Adversus Avatar answered Nov 11 '22 23:11

Adversus