Results 1 to 3 of 3

Thread: How to reimplement closeEvent, in the main window of an MDI application

  1. #1
    Join Date
    Aug 2009
    Posts
    5
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default How to reimplement closeEvent, in the main window of an MDI application

    uname -a: Linux bartleby 2.6.28-14-generic #47-Ubuntu SMP Sat Jul 25 01:19:55 UTC 2009 x86_64 GNU/Linux
    moc -v: Qt Meta Object Compiler version 61 (Qt 4.5.0)

    Hello, gents,

    In an MDI application, what is the correct way to reimplement closeEvent in the main window (the one that contains a QMdiArea)?

    Assume that the MDI child class (derived from QMdiSubWindow) reimplements closeEvent, popping up a message box with discard/save/cancel buttons, and accepts or ignores the event appropriately.

    Trying to close the main window should attempt to close the children (f.i., QMdiArea::closeAllSubWindows), and NOT exit the application if one of them ignored its close event.

    The funny thing is, after some hours on my own, I tried compiling TrollTech's own example, at
    http://doc.qtsoftware.com/4.5/mainwindows-mdi.html

    and it fails just the same. Try to open an MDI child, write some text on it, and close the main window: it will ask for the document to be saved first. If you choose "Cancel", the applications closes anyway!

    Has anybody successfully worked around this? Could you try if your own MDI applications stay open when canceling a save on a child?

    Thanks for your comments in advance.

    - - -

    Thinks I have tried, in a minimal MDI application of my own:

    Test conditions:
    * The MDI child window implements closeEvent, popping a message box with discard/save/cancel buttons, and ignores or accepts the event accordingly.
    * The main window starts with only one MDI child. In this minimal test, the child is always considered "dirty" (if you close it, it will pop up a message box requesting to be saved).
    * Closing the MDI child works as expected, for the three cases of the message box. The question is, what happens when closing the main window.
    * There are good old "printf"s all around, to trace the flow of events.

    Alternatives tested:

    1) Not reimplementing closeEvent in the main window at all.
    Effect: the MDI child won't get a close event, and die without any message box.

    2) The implementation of closeEvent in the main window calls mdiarea->closeAllSubWindows(), and nothing else.
    Effect: the MDI child pops up the message box; when pressing "Cancel", the closeEvent in the MDI child correctly ignores the event. But the main window closes anyway.
    Comment: as expected, since I have not ignored the event in the main window itself. The question is, on which condition?

    3) The implementation of closeEvent in the main window calls mdiarea->closeAllSubWindows(), and afterwards accepts or ignores the event depending on whether mdiarea->activeSubWindow() returns zero or non-zero.
    Effect: same as in the TrollTech example - the MDI child pops up the message box; when pressing "Cancel", the closeEvent in the MDI child correctly ignores the event. But mdiarea->activeSubWindow() returns zero nevertheless (why??), and the main window closes.
    Comment: no surprise here, since this is what the TrollTech example is doing.

    4) The implementation of closeEvent in the main window calls mdiarea->closeAllSubWindows(), and afterwards accepts or ignores the event depending on whether mdiarea->subWindowList().isEmpty() is true or not.
    Effect: the opposite, sort of. Closing the main window gets the MDI child pop-up, and pressing "Cancel" keeps both child and main window alive. So far so good. But when closing the main window and pressing "Close without saving" (discard) instead, the MDI child accepts the event and closes (good), but mdiarea->subWindowList().isEmpty() still returns false and the main window remains open (bad).

    So, what is the condition for accepting or ignoring the closeEvent in the main window?

    Apparently, any solution would depend on the order in which events are fired (which is not good).

  2. #2
    Join Date
    Aug 2009
    Posts
    5
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: How to reimplement closeEvent, in the main window of an MDI application

    If somebody is interested, a workaround is:

    In the main window's closeEvent implementation, after calling QMdiArea::closeAllSubWindows() but before testing for QMdiArea::activeSubWindow(), call QMdiArea::activateNextSubWindow(). This seems to do the trick, although I have not tested extensively.

    Still, the example application needs to be fixed.

  3. #3
    Join Date
    Aug 2009
    Posts
    5
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: How to reimplement closeEvent, in the main window of an MDI application

    I just found that the close() slot of widgets returns a bool, with a value precisely intended for the case at hand. So a better solution is probably not to use closeAllSubWindows() at all, and code instead the closeEvent as follows:
    Qt Code:
    1. void MainWindow::closeEvent (QCloseEvent* event)
    2. {
    3. QList<QMdiSubWindow*> list = mdi->subWindowList ();
    4.  
    5. for (int i = 0; i < list.size (); i++)
    6. if (!list[i]->close ()) {
    7. event->ignore ();
    8. return;
    9. }
    10.  
    11. event->accept ();
    12. }
    To copy to clipboard, switch view to plain text mode 
    which will stop the procedure at the first MDI child that cancels the event.

    I'm open to hear how other people have coded their MDI apps' closeEvent.

Similar Threads

  1. Creating a Main Window Application
    By gt.beta2 in forum Qt Tools
    Replies: 13
    Last Post: 24th February 2009, 19:45
  2. minimizing main window
    By eric in forum Qt Programming
    Replies: 4
    Last Post: 28th November 2007, 16:54
  3. accessing my main application window widget
    By jayw710 in forum Newbie
    Replies: 8
    Last Post: 15th November 2007, 19:33
  4. Independant window in an application
    By titoo in forum Qt Programming
    Replies: 4
    Last Post: 28th February 2007, 11:07
  5. cannot make a main window modal
    By Dark_Tower in forum Qt Programming
    Replies: 12
    Last Post: 23rd March 2006, 10:21

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.