简体   繁体   中英

Can you put QWidgets on the stack?

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:

  1. QWidgets only worked on the Heap
  2. That the pointer would delete error; automatically when the messagebox was closed.

I tried putting the QMessageBox on the stack, but it did not show.


Questions:

  1. Can I put this QMessageBox on the stack and have it work, and should I?
  2. Do I need to explicitly delete the QMessageBox pointer?
  3. Why is setting the parent to something beyond 0 important in this case?

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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM