Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt 在关闭QCore应用程序之前进行清理_Qt_Exit - Fatal编程技术网

Qt 在关闭QCore应用程序之前进行清理

Qt 在关闭QCore应用程序之前进行清理,qt,exit,Qt,Exit,我有一个基于控制台的QCoreApplication,它有定时器、套接字通信,还使用锁定互斥锁 当我手动关闭应用程序时,它会给出一个错误消息,表示某些互斥锁已锁定,并且超时。当用户关闭控制台应用程序时,有什么方法可以在控制台应用程序中进行清理吗?您可以连接到signal并在那里进行必要的清理。清理应由析构函数和子-父关系处理 使您的主对象(主对象中的一个)成为QApplication的子对象,以便在QApplication启动之前将其与其所有子对象一起销毁 你确定你杀死了所有的线程吗?如果是带有

我有一个基于控制台的
QCoreApplication
,它有定时器、套接字通信,还使用锁定互斥锁


当我手动关闭应用程序时,它会给出一个错误消息,表示某些互斥锁已锁定,并且超时。当用户关闭控制台应用程序时,有什么方法可以在控制台应用程序中进行清理吗?

您可以连接到signal并在那里进行必要的清理。

清理应由析构函数和子-父关系处理

使您的主对象(主对象中的一个)成为QApplication的子对象,以便在QApplication启动之前将其与其所有子对象一起销毁

你确定你杀死了所有的线程吗?如果是带有eventloop的线程,请确保在调用
QThread::wait()之前调用
QThread::quit()
退出eventloop

您还可以使用void
QApplication::qaddpostproutine(QtCleanUpFunction ptr)
做一些特别的清理

要调试这些消息,您可以使用
QtMsgHandler(QtMsgHandler h)
并编写自己的消息处理程序来捕获这些警告。如果可以模拟该问题,则可以在消息上设置断点,并在堆栈上查看消息的来源

void debugMessageHandler( QtMsgType type, const char *msg ){
    if(QString(msg).contains( "The message you can see in the console" )){
        int breakPointOnThisLine(0);    
    }

    switch ( type ) {
        case QtDebugMsg:
            fprintf( stderr, "Debug: %s\n", msg );
            break;
        case QtWarningMsg:
            fprintf( stderr, "Warning: %s\n", msg );
            break;
        case QtFatalMsg:
            fprintf( stderr, "Fatal: %s\n", msg );
            abort();
    }
}

为了清理析构函数和子-父关系,您可以捕获控制台关闭信号并调用应用程序实例
QCoreApplication::exit()

#include <csignal>
#include <QtCore/QCoreApplication>
using namespace std;

struct CleanExit{
    CleanExit() {
        signal(SIGINT, &CleanExit::exitQt);
        signal(SIGTERM, &CleanExit::exitQt);
        signal(SIGBREAK, &CleanExit::exitQt) ;
    }

    static void exitQt(int sig) {
        QCoreApplication::exit(0);
    }
};


int main(int argc, char *argv[])
{
    CleanExit cleanExit;
    QCoreApplication a(argc, argv);
    return a.exec();
}
#包括
#包括
使用名称空间std;
结构清理出口{
CleanExit(){
信号(SIGINT和CleanExit::exitQt);
信号(SIGTERM和CleanExit::exitQt);
信号(SIGBREAK和CleanExit::exitQt);
}
静态无效退出(int sig){
QCoreApplication::退出(0);
}
};
int main(int argc,char*argv[])
{
清洁出口清洁出口;
qcorea应用程序(argc、argv);
返回a.exec();
}

结果表明,按下“关闭”(标题栏上的红色x按钮)关闭命令行应用程序(在Win7和VS2010上选中)会将
状态控制\u C\u退出
信号传递给应用程序。使用此代码中止所有线程

线程“主线程”(0x980)已退出,代码为-1073741510 (0xc000013a)

线程“QThread”(0x2388)已退出,代码为 -1073741510(0xc000013a)

这意味着无法使用
QCoreApplication::aboutToQuit()
信号截获此消息

查看
winnt.h
ntstatus.h
。这是分配给对象的值 清单常量
状态控制\u C\u退出
。运行时只是 选择以代码结束程序以记录用户的取消
操作。

嗨,丹尼尔,我试过了,但连接的插槽中没有断点。文档说明调用QCoreApplication上的quit时会发出aboutToQuit信号。控制台应用程序的关闭是否调用quit()?谢谢,苏雷什。差不多完成了。调用exit(0)后,必须在信号处理程序exitQt()中不存在的地方执行特定于Qt的清理代码。因此,您必须将Qt清理代码绑定到aboutToQuit()信号。aboutToQuit信号仅在调用qApp->exit(0)时发出。c++11使其更容易:
信号(SIGTERM,[](int-sig){qApp->quit();})这没有完全工作。我已使清理相关对象成为QApplication的子对象。当窗口正常关闭时,析构函数被正确调用。但在系统关闭/注销时,QApplicationChild析构函数永远不会被调用。不支持从unix信号调用Qt函数(可能会挂起、损坏数据等)。看见此代码可能使用户无法通过ctrl-c退出程序。另请参见使用setConsoletrlHandler()拦截这些,并调用qApp->exit(42)