Reputation: 2492
Backstory:
I had some of my code reviewed, and I had made a local QMessageBox
for displaying an error, and allocated it to the heap:
if (getAutopilotList.error() == 0) {
QMessageBox* error = new QMessageBox(0);
error->setDetailedText(getAutopilotList.errorString());
error->setText("something");
error->setWindowTitle(tr("Error!"));
error->show();
return;
}
The developer said:
This pointer will leak, you are setting no parent and you never delete it. Here as well you do not need a pointer. As for the parent do not use 0, but Core::ICore::mainWindow().
I was confused because I thought:
delete error;
automatically when the messagebox was closed.I tried putting the QMessageBox on the stack, but it did not show.
delete
the QMessageBox pointer?Upvotes: 4
Views: 198
Reputation: 7438
QWidget on stack works, but not practical for most cases as the objects on stack are deleted, when the scope is left.
Take a look at any (many-many) Qt examples, and you'll find the pattern:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow window; //inherits from QWidget, created on stack
window.show();
return app.exec();
}
1) Concerning the question "QWidget on stack"- It should be the prove, that it works and official. But again this and the QDialog::exec are pretty the only use cases for QWidgets on stack.
2) It won't harm. If your coding rules require to call delete for each new - do it. Otherwise, set Qt::WA_DeleteOnClose properly, and let it be deleted on close.
3)Regarding parent 0: You are safe when loosing the reference to the pointer having a parent. If the parent is deleted, all children are deleted automatically (also those, you may have been forgotten about). So for long-running applications, the "memory leak" will be only temporarily. With parent =0 it won't leak in c++ sense, and this makes impossible for memory checkers to detect such leaks. The pointer is still accessible using some QObject-tree traversing functions.
Upvotes: 3
Reputation: 3278
In principle, you can create a QWidget object on the stack. Here, it wouldn't work because the call to error->show()
does not show the message box immediately, it just schedules a display when back to the main even loop, at which time the object will be destroyed. For that reason, delete
ing the QMessageBox
is not going to work either. Setting the parent gives the responsability of the object destruction to the parent, when the parent is itself destroyed, and it is a good idea.
However, if I understand what you want to do, you want to wait for the user to click on the OK button before the return
. If that's the case, you'd better use the static QMessageBox
functions, such as QMessageBox::warning.
If you want a persistent message box, then your code is OK, but you should add the following call:
error->setAttribute(Qt::WA_DeleteOnClose);
This will trigger deletion when the corresponding window is closed.
Upvotes: 4
Reputation: 16685
I tried putting the QMessageBox on the stack, but it did not show.
Because it will get destroyed immediately when thread goes out of the scope. You had to use QMessageBox::exec()
to run it in block-mode.
Upvotes: 4