Results 1 to 8 of 8

Thread: How to get focus back to main window if non-modal dialog is closed?

  1. #1
    Join Date
    May 2010
    Posts
    86
    Thanks
    17
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default How to get focus back to main window if non-modal dialog is closed?

    DIALOG:

    Extract from the constructor of dialog:

    Qt Code:
    1. setWindowFlags(Qt::WindowTitleHint | Qt::Dialog | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint | Qt::CustomizeWindowHint);
    2. setModal(false);
    To copy to clipboard, switch view to plain text mode 

    cpp:
    Qt Code:
    1. void FindDialog::closeEvent(QCloseEvent *e)
    2. {
    3. emit closing(true);
    4. QDialog::closeEvent(e);
    5. }
    To copy to clipboard, switch view to plain text mode 

    h:
    Qt Code:
    1. protected:
    2. void closeEvent(QCloseEvent *e);
    3.  
    4. signals:
    5. void closing(bool visible);
    To copy to clipboard, switch view to plain text mode 

    MAIN WINDOW:

    cpp:
    Qt Code:
    1. findDialog = new FindDialog;
    2. findDialog->setVisible(false);
    3. findDialog->setMeasurements(&measurements);
    4. connect(findDialog, SIGNAL(closing(bool)), this, SLOT(setShown(bool)));
    To copy to clipboard, switch view to plain text mode 

    h:
    Qt Code:
    1. FindDialog *findDialog;
    To copy to clipboard, switch view to plain text mode 

    Even if I change setShown to setFocus it doesn't make any difference.
    How could I get back the focus to main window? It is crucial if user meanwhile activated a different application and then clicked back on dialog and closes it...

    findDialog->setVisible(true); is called when a menu item is triggered.

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: How to get focus back to main window if non-modal dialog is closed?

    See QWidget::activateWindow() and QWidget::raise (). Be aware the Windows places some restrictions on the activateWindow() call.

  3. #3
    Join Date
    May 2010
    Posts
    86
    Thanks
    17
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How to get focus back to main window if non-modal dialog is closed?

    Thanks, Chris!

    It looks like FindDialog::closeEvent(QCloseEvent *e) is not even called since it is a non-modal window. Anyway, it is the needed behavior since I don't want to lose search results in the dialog. So, anytime the user clicks on 'Hide' button, it is really makes it hidden, not closed. I thought that closeEvent is called even if the window is not destroyed, but user clicks on e.g. close (top right) button, but not.

    However, I want to inform main window that either 'Hide' or top right close button is clicked, so it could take the control and visibility back. What can I do in this case?
    Should I check close()?

    Another problem: it looks like if a non-modal dialog is opened, then the main window is closed by the user, the non-modal dialog still stays open and the program keeps running.
    In my case, the closeEvent is finally called if I close this last window of non-modal dialog, and it strangely gives control/visibility back to the earlier closed main window.

    Very strange, however funny.
    Last edited by falconium; 21st April 2011 at 06:01.

  4. #4
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: How to get focus back to main window if non-modal dialog is closed?

    The title bar close tool should trigger closeEvent() when clicked. I guess you want to intercept that and hide() the dialog then ignore the event. Your dialog also has a hideEvent() that you could use.

    Closing the window does not destroy the object unless you have set the relevant window Qt::WA_DeleteOnClose attribute. In the typical main() the first main window is allocated on the stack and is not destroyed until the exec() loop exits after all the top-level windows close.

  5. The following user says thank you to ChrisW67 for this useful post:

    Cupidvogel (1st January 2016)

  6. #5
    Join Date
    May 2010
    Posts
    86
    Thanks
    17
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How to get focus back to main window if non-modal dialog is closed?

    Thanks, Chris.
    This is the problem, that closeEvent() is not called when I close this non-modal dialog by clicking on title bar close button. It is only called - as I wrote - in case of closing main window.
    I have debugged it to see whether it goes into closeEvent(), but doesn't. Strange. I'm using the new Qt framework 4.7.3.

  7. #6
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: How to get focus back to main window if non-modal dialog is closed?

    Works just fine here with this code:
    Qt Code:
    1. #include <QtGui>
    2. #include <QDebug>
    3.  
    4. class Dialog: public QDialog {
    5. Q_OBJECT
    6. public:
    7. Dialog(QWidget *p = 0): QDialog(p) {
    8. QVBoxLayout *layout = new QVBoxLayout;
    9. QLabel *label1 = new QLabel("Dialog Label", this);
    10. layout->addWidget(label1);
    11. setLayout(layout);
    12. }
    13. protected:
    14. void closeEvent(QCloseEvent *e) {
    15. qDebug() << "Dialog closeEvent called";
    16. }
    17. public slots:
    18. private:
    19. };
    20.  
    21. class MainWindow: public QMainWindow {
    22. Q_OBJECT
    23. public:
    24. MainWindow(QWidget *p = 0): QMainWindow(p) {
    25. QLabel *label = new QLabel("MainWindow label", this);
    26. setCentralWidget(label);
    27.  
    28. QTimer::singleShot(3000, this, SLOT(openDialog()));
    29. }
    30. public slots:
    31. void openDialog() {
    32. // With parentless dialog main window closing will not terminate app
    33. dialog = new Dialog;
    34. dialog->setAttribute(Qt::WA_DeleteOnClose, true);
    35. dialog->show();
    36.  
    37. // With parented dialog the main window close terminates app
    38. // dialog = new Dialog(this);
    39. // dialog->show();
    40. }
    41. protected:
    42. void closeEvent(QCloseEvent *e) {
    43. qDebug() << "MainWindow closeEvent called";
    44. }
    45. private:
    46. Dialog *dialog;
    47. };
    48.  
    49. int main(int argc, char *argv[])
    50. {
    51. QApplication app(argc, argv);
    52.  
    53. MainWindow m;
    54. m.show();
    55. return app.exec();
    56. }
    57. #include "main.moc"
    To copy to clipboard, switch view to plain text mode 
    Both closeEvents are called on clicking the title bar close icon (Qt4.6.3 Linux and 4.7.0 Windows)

  8. The following 2 users say thank you to ChrisW67 for this useful post:

    Cupidvogel (1st January 2016), falconium (22nd April 2011)

  9. #7
    Join Date
    May 2010
    Posts
    86
    Thanks
    17
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How to get focus back to main window if non-modal dialog is closed?

    Hi Chris,

    Yes, because you set Qt::WA_DeleteOnClose attribute, but my aim was not to delete the dialog, just to hide it. Thank you for your contribution however!
    Meanwhile I have figured out what an evident mistake I made:

    If user clicks on 'Hide' button of dialog box, then the following should be called for the dialog:

    this->done(QDialog::Accepted);

    I also forgot to add the following to closeEvent() if user clicks on title bar close button:

    e->accept();

    So, even if it is accepted, the dialog stays in memory and main window gets the focus back.

    I still need to play with main window not to show when it was 'closed' and later user 'closes' Find dialog. If main window is closed, then the whole application should quit. Maybe I would need to force it in closeEvent... I'll get back with the solution.

  10. #8
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: How to get focus back to main window if non-modal dialog is closed?

    I don't know what this "hide" button is. The dialog title bar has a close button, that does exactly what it is advertised to do. It calls the closeEvent(), which you were claiming it did not do. If that event is accepted (the default) then, to quote the QCloseEvent docs (emphasis mine):
    Close events contain a flag that indicates whether the receiver wants the widget to be closed or not. When a widget accepts the close event, it is hidden (and destroyed if it was created with the Qt::WA_DeleteOnClose flag).
    The corollary is that the dialog is not deleted on close if the Qt::WA_DeleteOnClose attribute is not set. The Qt::WA_DeleteOnClose is set only so the memory is not leaked if you close the parent-less dialog because you cannot rely a QObject parent to do it for you. If you want a mode-less top-level dialog that doesn't delete itself on close then leave out the attribute, but you have to manage the object lifetime elsewhere. Qt::WA_DeleteOnClose has no effect on whether the closeEvent() is called.

    To make the whole application quit if the main window is closed then create the mode-less dialog as a child of the main window. There's no magic here.

    This example demonstrates your requirement. Take careful note of when the dialog is destroyed.
    • Hides when its close button is clicked
    • Hides when its "Hide Me" button is clicked
    • Shows when the main window calls show()
    • Is not considered a top-level window that stops the main event loop exiting

    Qt Code:
    1. #include <QtGui>
    2. #include <QDebug>
    3.  
    4. class Dialog: public QDialog {
    5. Q_OBJECT
    6. public:
    7. Dialog(QWidget *p = 0): QDialog(p) {
    8. qDebug() << this << "created";
    9. QPushButton *pb = new QPushButton("Hide Me", this);
    10. connect(pb, SIGNAL(clicked()), this, SLOT(hide()));
    11. QVBoxLayout *layout = new QVBoxLayout;
    12. layout->addWidget(pb);
    13. setLayout(layout);
    14. }
    15. ~Dialog() {
    16. qDebug() << this << "destroyed";
    17. }
    18. protected:
    19. void closeEvent(QCloseEvent *e) { qDebug() << this << "closeEvent called"; }
    20. };
    21.  
    22. class MainWindow: public QMainWindow {
    23. Q_OBJECT
    24. public:
    25. MainWindow(QWidget *p = 0): QMainWindow(p), dialog(0) {
    26. QPushButton *pb = new QPushButton("Show dialog", this);
    27. connect(pb, SIGNAL(clicked()), this, SLOT(openDialog()));
    28. setCentralWidget(pb);
    29. }
    30. ~MainWindow() { qDebug() << "MainWindow destroyed:" << this; }
    31. public slots:
    32. void openDialog() {
    33. if (!dialog)
    34. dialog = new Dialog(this);
    35. dialog->show();
    36. }
    37. protected:
    38. void closeEvent(QCloseEvent *e) {
    39. qDebug() << this << "closeEvent called";
    40. }
    41. private:
    42. Dialog *dialog;
    43. };
    44.  
    45. int main(int argc, char *argv[])
    46. {
    47. QApplication app(argc, argv);
    48.  
    49. MainWindow m;
    50. m.show();
    51. return app.exec();
    52. }
    53. #include "main.moc"
    To copy to clipboard, switch view to plain text mode 

  11. The following 2 users say thank you to ChrisW67 for this useful post:

    Cupidvogel (1st January 2016), falconium (24th April 2011)

Similar Threads

  1. Replies: 2
    Last Post: 4th August 2010, 20:10
  2. Replies: 3
    Last Post: 1st February 2009, 16:49
  3. Replies: 5
    Last Post: 5th August 2006, 00:44
  4. Replies: 3
    Last Post: 23rd July 2006, 19:02
  5. cannot make a main window modal
    By Dark_Tower in forum Qt Programming
    Replies: 12
    Last Post: 23rd March 2006, 11:21

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.