Results 1 to 7 of 7

Thread: WA_DeleteOnClose and exec()

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Aug 2010
    Posts
    65
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Windows

    Default WA_DeleteOnClose and exec()

    I have created a child class of QDialog (NDialog). This class has WA_DeleteOnClose set up in its constructor. This is done because the parent of these dialogs persists for the duration of the entire program and there may be countless dialogs throughout the course of the program, so I'd rather not wait for the end of the program, and thus the destruction of the parent, to destroy all the countless dialogs at once. So I thought it better to simply set WA_DeleteOnClose on each dialog so that, once OK, Cancel or whatnot is pressed, the dialog gets deleted.

    This works just fine, as far as I can tell.

    However, the class has a static method Error which displays a modal (all others are modeless) dialog with the given error message. In this case, and this case only, WA_DeleteOnClose causes a crash. If I remove this attribute, the error dialog closes just fine, but theoretically won't be deleted until the end of the program.

    Should it help, here's the relevant code:
    Qt Code:
    1. class NDialog : public QDialog
    2. {
    3. Q_OBJECT
    4.  
    5. QVBoxLayout Layout;//layout box of the dialog
    6. public:
    7. NDialog(QString title,QWidget* parent=0, Qt::WindowFlags f=0) : QDialog(parent,f)
    8. {
    9. setAttribute(Qt::WA_DeleteOnClose);
    10. setWindowTitle(title);
    11. setLayout(&Layout);
    12. };
    13. void AddWidget(QWidget* widget) //add a widget to the layout
    14. {
    15. Layout.addWidget(widget);
    16. };
    17. static void Error(QString value) //diplays error message
    18. {
    19. NDialog* dlg = new NDialog("ERROR");
    20. dlg->setAttribute(Qt::WA_DeleteOnClose,false);
    21. QLabel msg(value);
    22. dlg->AddWidget(&msg);
    23.  
    24. QPushButton ok("OK");
    25. connect(&ok,SIGNAL(clicked()),dlg,SLOT(close()));
    26. dlg->AddWidget(&ok);
    27.  
    28. dlg->exec();
    29. };
    30. };
    To copy to clipboard, switch view to plain text mode 

    This is the case where the code works. If I remove the "dlg->setAttribute(Qt::WA_DeleteOnClose,false);" line, the program crashes.

    This is the only time I use dlg->exec() as opposed to dlg->show(). Does this have anything to do with it?

  2. #2
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: WA_DeleteOnClose and exec()

    Not sure of the crash, as you have not mentioned when the program crashes, or at least the stack trace.

    Anyways following is a better, and good way to do. I recommend it this way,

    Qt Code:
    1. class NDialog : public QDialog
    2. {
    3. Q_OBJECT
    4. ...
    5. public:
    6. ...
    7. static void Error(QString value) //diplays error message
    8. {
    9. NDialog dlg("ERROR");
    10. dlg.setAttribute(Qt::WA_DeleteOnClose,false);
    11. QLabel msg(value);
    12. dlg.AddWidget(&msg);
    13.  
    14. QPushButton ok("OK");
    15. connect(&ok,SIGNAL(clicked()),&dlg,SLOT(close()));
    16. dlg.AddWidget(&ok);
    17.  
    18. dlg.exec();
    19. };
    20. };
    To copy to clipboard, switch view to plain text mode 

    or

    Qt Code:
    1. class NDialog : public QDialog
    2. {
    3. Q_OBJECT
    4. ...
    5. public:
    6. ...
    7. static void Error(QString value) //diplays error message
    8. {
    9. NDialog* dlg = new NDialog("ERROR");
    10. dlg->setAttribute(Qt::WA_DeleteOnClose,false);
    11. QLabel* msg = QLabel(value,dlg);
    12. dlg->AddWidget(msg);
    13.  
    14. QPushButton* ok = new QPushButton ("OK", dlg);
    15. connect(ok,SIGNAL(clicked()),dlg,SLOT(close()));
    16. connect(ok,SIGNAL(clicked()),dlg,SLOT(deleteLater()));
    17. dlg->AddWidget(ok);
    18.  
    19. dlg->exec();
    20. };
    21. };
    To copy to clipboard, switch view to plain text mode 

    for both of the above examples you don't need to use WA_DeleteOnClose flag
    Last edited by Santosh Reddy; 7th August 2011 at 06:14.

  3. #3
    Join Date
    Aug 2010
    Posts
    65
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: WA_DeleteOnClose and exec()

    Ah, apologies. Given how the problem had to do with DeleteOnClose, I took it for granted that the crash occurs when the dialog is closed. And the erros given is a "Debug Assertion Error".

    And both methods work, so thanks. What I find odd is that these dialogs work perfectly if they're modeless (::show()), but only crash when they're modal (::exec()).

  4. #4
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: WA_DeleteOnClose and exec()

    Ok, it is obvious that the WA_DeleteOnClose flag if set will delete the dialog when closed, and then as dialog is a object defined on stack it will deleted when the block scope exits, it is here your program will crash, as it is deleting the dialog which is already deleted when you closed it.

    So conclusion, use WA_DeleteOnClose flag for objects / widgets created on heap.

  5. #5
    Join Date
    Aug 2010
    Posts
    65
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: WA_DeleteOnClose and exec()

    Yes, of course, but you'll see in my original post that it was created on the heap, but was still giving me the crash regardless. I admit that the first time I wrote the code, I created it on the stack and it took me a few seconds to realize how silly it was, so I created it on the heap. The surprise was to find that it still crashed.

  6. #6
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: WA_DeleteOnClose and exec()

    Check again you are you missing something? You still have QLabel and QPushButton defined on stack? which were also deleted when the dialog is deleted, as dialog takes the ownership of the widget when any widget is added to it.

    I hope you got my point.

  7. #7
    Join Date
    Aug 2010
    Posts
    65
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: WA_DeleteOnClose and exec()

    Ah, correct. Hadn't thought to create all the other objects on the stack. Touché.

    Thanks.

Similar Threads

  1. Qt::WA_DeleteOnClose - object persistance
    By ranna in forum Qt Programming
    Replies: 0
    Last Post: 4th June 2009, 08:08
  2. Qt::WA_DeleteOnClose while a child QDialog is executed
    By nooky59 in forum Qt Programming
    Replies: 4
    Last Post: 11th July 2008, 13:45
  3. app.exec() never returns?
    By stealth86 in forum Qt Programming
    Replies: 3
    Last Post: 17th July 2007, 19:41
  4. Qt::WA_DeleteOnClose
    By merlvingian in forum Newbie
    Replies: 3
    Last Post: 22nd November 2006, 19:38
  5. How to use QThread::exec()
    By intensifi in forum Qt Programming
    Replies: 4
    Last Post: 10th February 2006, 17:00

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.