qtmulti-window

How to close the qt application when setQuitOnLastWindowClosed(false)


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);
}

Solution

  • 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.