1

I want to run my destructor before click the close button of Qt console application.I found this on stackoverflow,Destructor not called in Qt console scenario .

I have tried to get the return value ,and return the value after.but it is nothing to help.


class MyClass
{
    Q_OBJECT
public:
    MyClass()
    {
        qDebug() << "MyClass()";
    }
    ~MyClass()
    {
        qDebug() << "~MyClass()";
    }
};

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

    MyClass my;

    int ret = a.exec();

    qDebug() << "this line will not run.";

    return ret;
}
  1. I want to know why it doesn't run my destructor.

  2. If I want to run it.how?

I want it to output MyClass() and this line will not run. and ~MyClass() when I click the close button.

Liu Guangxuan
  • 119
  • 1
  • 7
  • Because calling .exec on QCoreApplication enters the main event loop and waits until exit() is called. – TonySalimi Aug 07 '19 at 13:25
  • 3
    The documentation for `QCoreApplication::exec()` is self-explanatory about this .... "We recommend that you connect clean-up code to the `aboutToQuit()` signal, instead of putting it in your application's `main()` function because on some platforms the `exec()` call may not return. For example, on Windows when the user logs off, the system terminates the process after Qt closes all top-level windows. Hence, there is no guarantee that the application will have time to exit its event loop and execute code at the end of the `main()` function after the `exec()` call." – Peter Aug 07 '19 at 13:26
  • Your class is instanciated on the stack and will be destructed once you get out of your scope. Use a pointer to allocate it on the heap and call the destructor with delete when app is about to quit : https://doc.qt.io/qt-5/qcoreapplication.html#aboutToQuit – Greg Aug 07 '19 at 13:28
  • I don't have time to write an answer right now (so anybody, feel free to do so), but solution to your problem should be found behind these two links: https://doc.qt.io/qt-5/unix-signals.html and https://stackoverflow.com/q/26658707/1717300 (note: not duplicate, doesn't cover how to do it in Qt). – hyde Aug 07 '19 at 14:04

1 Answers1

1

You probably want to do something like this. I'm not sure if it works on Windows since I don't have it right now, but it work on Linux.

#include <signal.h>
#include <QCoreApplication>
#include <QObject>

class MyClass : public QObject
{
    Q_OBJECT
public:
    MyClass()
    {
        qDebug() << "MyClass()";
    }
    ~MyClass()
    {
        qDebug() << "~MyClass()";
    }
};

void SigInt_Handler(int)
{
    qDebug() << "Interrupt received";
    qApp->quit();
}

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

    MyClass my;

    signal(SIGINT, &SigInt_Handler);

    int ret = a.exec();

    return ret;
}

Also your MyClass should extend QObject if you use the Q_OBJECT macro in it.

When pressing Ctrl+C this will be printed:

Interrupt received
~MyClass()
Silvano Cerza
  • 954
  • 5
  • 16
  • 1
    I did a quick test, and in that it seems `aboutToQuit` is not emitted, when I close the console window. Logging to file and flushing after every log line, the lines before `a.exec()` are written, but nothing after it, nor from `aboutToQuit` receiver lambda. – hyde Aug 07 '19 at 13:57
  • Yep, I was a bit too quick to answer, I thought it would work but it's not. I'm trying other approaches right now, but I don't think there's an easy way. – Silvano Cerza Aug 07 '19 at 14:00
  • 1
    See my comment under the Q. – hyde Aug 07 '19 at 14:05
  • @hyde yep, that actually works, I've updated the answer. – Silvano Cerza Aug 07 '19 at 14:20
  • Yeah, but Qt isn't "async safe" so you are not allowed to call Qt methods from signal handlers... So the links under the Q. – hyde Aug 07 '19 at 14:45