0

I wish to create a project including 3 windows: mainWindow, childWindow1, childWindow2, and only one window should show at a time. And I can switch between these windows.

So I have three tasks:

  1. I place two buttons in the mainWindow and want to use them to make one of the child windows showing and the main window hiding.
  2. And when I close the child window, I wish to show the main window.
  3. When I close the main window, terminate the whole application.

I first had a problem: If I close the child window, the application exit. So I use the qApp.setQuitOnLastWindowClosed(false), and I got task 2 done. But another problem occured: If I close the main window, the program is still running.

Last problem: How to show the child window in the task bar? It looks wired to run a program which can't be found in the taskbar.

I search everywhere I could, any help would be really appreciated!

main.cpp:

int main()
{
  QApplication a(argc, argv);
  a.setQuitOnLastWindowClosed(false);
  MainWindow mainWindow;
  mainWindow.show();
  return a.exec();
}

mainWindow.cpp:

void mainWindow::button1Clicked()
{
  this->hide();
  childWindow1 = new ChildWindow1(this);
  connect(childWindow1, &QMainWindow::destroyed, this, &QMainWindow::show);
  childWindow1->setWindowModality(Qt::WindowModal);
  childWindow1->show();
}

childWindow1.cpp

ChildWindow1::ChildWindow1(QWidget *parent)
: QMainWindow(parent)
{
  ui.setupUi(this);
  setAttribute(Qt::WA_DeleteOnClose);
}
Chen
  • 15
  • 1
  • 5
  • Don't you just need to override [`QWidget::closeEvent`](http://doc.qt.io/qt-5/qwidget.html#closeEvent) in your `MainWindow` class (and possibly also the child window classes)? – G.M. Feb 18 '18 at 10:43
  • @G.M. Thank you! I solved the first problem! Here is the solution:1. comment `a.setQuitOnLastWindowClosed(false);`; 2. overrride `QWidget::closeEvent`, and in closeEvent, `qobject_cast(parent())->show(); event->accept();` – Chen Feb 18 '18 at 11:31

1 Answers1

1

To achieve this you need to do the following:

  1. In your main.cpp:

    QApplication a(argc, argv);
    a.setQuitOnLastWindowClosed(false);
    MainWindow w;
    QObject::connect(&w, &MainWindow::exited, &a, &QApplication::quit);
    w.show();
    return a.exec();
    

exited signal would be used to exit the application after closing the main window.

  1. In your MainWindow you should reimplement closeEvent like this:

    void MainWindow::closeEvent(QCloseEvent *event)
    {
        QMainWindow::closeEvent(event);
        emit exited();
    }
    

Don't forget to add exited() to MainWindow signals section;

  1. Finally, code for creating new windows should be the following:

    child1 = new ChildWindow;
    child1->setAttribute(Qt::WA_DeleteOnClose);
    connect(child1, &QObject::destroyed, this, &QWidget::show);
    child1->show();
    hide();
    

Note that I don't pass this as a parent for a ChildWindow, this allows it to appear in the task bar.

So, creating a new ChildWindow will hide the main window, closing the ChildWindow will delete it automatically (that's another reason why you don't need to pass parent to ChildWindow constructor) and closing MainWindow will close the whole application thanks to our exited signal.

Bearded Beaver
  • 646
  • 4
  • 21
  • Thank you so much! It works perfectly! So I got 2 answers to solve my problem: 1. `setQuitOnLastWindowClosed(true);`, reimplement `closeEvent` in 2 ChildWindow, and show mainWindow before processing close event; 2. `setQuitOnLastWindowClosed(false);`, reimplement `closeEvent` in MainWindow, and emit a signal to terminate the application. – Chen Feb 18 '18 at 12:05
  • `qobject_cast(parent())->show();` is not the best idea as long as `parent` can be `nullptr`. For example in my solution it is. – Bearded Beaver Feb 18 '18 at 12:16