0

The following code snippet opens two windows, w1 and w2. How can one force w2 to close when w1 is closed by the user? As in the comment, the connect function is not working that way.

#include <QApplication>
#include <QtGui>
#include <QtCore>
#include <QtWidgets>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QWidget w1;
    w1.setWindowTitle("w1");
    w1.show();

    QWidget w2;
    w2.setWindowTitle("w2");
    w2.show();

    // when w1 is closed by the user, I would like w2 to close, too.
    // However, it won't happen, even though the code compiles fine.
    QObject::connect(&w1, &QObject::destroyed, &w2, &QWidget::close);

    return a.exec();
}

Edit In my case, those two widgets are designed in two separate libraries, so they cannot communicate with each other. Thus, the close event is not applicable.

Edit Eventually my solution to my problem is based on the answer by @JeremyFriesner: emit a closed signal in closeEvent of w1, and connect this (instead of QObject::destroyed) to w2.

sofname
  • 429
  • 1
  • 5
  • 20
  • Does this answer your question? [Qt: How do I handle the event of the user pressing the 'X' (close) button?](https://stackoverflow.com/questions/17480984/qt-how-do-i-handle-the-event-of-the-user-pressing-the-x-close-button) – David Grayson Dec 01 '21 at 02:54
  • 2
    I think the `Destroyed` signal only happens when the object goes out of scope and its memory is freed, which would happen when `main` returns. – David Grayson Dec 01 '21 at 02:54
  • A basic debugging investigation would involve connecting something else to that signal and setting a breakpoint or outputting a message, to see if it's actually being triggered at all. – paddy Dec 01 '21 at 02:55
  • @DavidGrayson Thanks for that. Unfortunately, that won't answer my question. – sofname Dec 01 '21 at 02:58
  • The close event could help. You may want to subclass one of the QWidgets and listen for the close event or install an event filter in a different class – drescherjm Dec 01 '21 at 02:59
  • @paddy You're right. I think it is not triggerd from what I see. So, my question would be what is the right thing to do? – sofname Dec 01 '21 at 03:00
  • @drescherjm In the case those two windows can communicate directly with each other, the close event helps. However, in my case, those two windows should not talk to each other. In fact, those two windows are designed in two separate libraries. – sofname Dec 01 '21 at 03:04
  • 1
    All literature and similar Q&A results that I've seen have the same answer: handle the `closeEvent`. – paddy Dec 01 '21 at 03:05
  • I believe you can use an event filter but the filter would have to know about both widgets. [https://doc.qt.io/qt-5/eventsandfilters.html#event-filters](https://doc.qt.io/qt-5/eventsandfilters.html#event-filters) – drescherjm Dec 01 '21 at 03:07

1 Answers1

2

This modified version of your program shows how you could do it by overriding the closeEvent(QCloseEvent *) method on your w1 widget:

#include <QApplication>
#include <QtGui>
#include <QtCore>
#include <QtWidgets>

class MyWidget : public QWidget
{
public:
   MyWidget(QWidget * closeHim) : _closeHim(closeHim)
   {
      // empty
   }

   virtual void closeEvent(QCloseEvent * e)
   {
      QWidget::closeEvent(e);
      if (_closeHim) _closeHim->close();
   }

private:
   QWidget * _closeHim;
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QWidget w2;
    w2.setWindowTitle("w2");
    w2.show();

    MyWidget w1(&w2);
    w1.setWindowTitle("w1");
    w1.show();

    return a.exec();
}

If you wanted to do it more elegantly, you could have your closeEvent() method-override emit a signal instead of calling a method on a pointer; that way you wouldn't have a direct dependency between the two classes, which would give you more flexibility in the future.

Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234