如何在关闭 Qt 控制台应用程序之前运行我的析构函数?

Posted

技术标签:

【中文标题】如何在关闭 Qt 控制台应用程序之前运行我的析构函数?【英文标题】:How to run my destructor before close the Qt Console Application? 【发布时间】:2019-08-07 13:20:23 【问题描述】:

我想在单击 Qt 控制台应用程序的关闭按钮之前运行我的析构函数。我在 *** 上找到了这个,Destructor not called in Qt console scenario。

我尝试获取返回值,然后返回值。但是没有任何帮助。


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;

    我想知道为什么它不运行我的析构函数。

    如果我想运行它。如何?

我希望它在单击关闭按钮时输出MyClass()this line will not run.~MyClass()

【问题讨论】:

因为在 QCoreApplication 上调用 .exec 会进入主事件循环并等待直到 exit() 被调用。 QCoreApplication::exec() 的文档对此一目了然......“我们建议您将清理代码连接到 aboutToQuit() 信号,而不是将其放入应用程序的 @987654331 @ 函数,因为在某些平台上exec() 调用可能不会返回。例如,在 Windows 上,当用户注销时,系统会在 Qt 关闭所有***窗口后终止进程。因此,不能保证应用程序将在exec() 调用之后,有时间退出其事件循环并在main() 函数的末尾执行代码。” 你的类在堆栈上被实例化,一旦你离开你的范围就会被破坏。使用指针在堆上分配它,并在应用程序即将退出时使用 delete 调用析构函数:doc.qt.io/qt-5/qcoreapplication.html#aboutToQuit 我现在没有时间写一个答案(所以任何人都可以这样做),但是您的问题的解决方案应该在这两个链接后面找到:doc.qt.io/qt-5/unix-signals.html 和 @987654324 @(注意:不重复,不包括如何在 Qt 中做到这一点)。 【参考方案1】:

你可能想做这样的事情。我不确定它是否适用于 Windows,因为我现在没有它,但它适用于 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;

如果您在其中使用Q_OBJECT 宏,您的MyClass 也应该扩展QObject

当按下Ctrl+C 时会打印出来:

Interrupt received
~MyClass()

【讨论】:

我做了一个快速测试,当我关闭控制台窗口时,似乎没有发出aboutToQuit。在每个日志行之后记录到文件并刷新,a.exec() 之前的行被写入,但之后没有任何内容,aboutToQuit 接收器 lambda 也没有。 是的,我回答得太快了,我认为它会起作用,但事实并非如此。我现在正在尝试其他方法,但我认为没有简单的方法。 看我在Q下的评论。 @hyde 是的,这确实有效,我已经更新了答案。 是的,但是 Qt 不是“异步安全的”,所以你不能从信号处理程序中调用 Qt 方法......所以 Q 下的链接。

以上是关于如何在关闭 Qt 控制台应用程序之前运行我的析构函数?的主要内容,如果未能解决你的问题,请参考以下文章

Qt:当用户关闭它时,在控制台应用程序中检测到 QTcpSocket 断开连接

C# 的析构

C++ 虚拟析构函数 (virtual destructor)

2-Qt关闭子窗口时执行特定代码

应用程序停止后Qt关闭托盘图标

类与其动态内存分配