项目的qt程序想要再linux下ctrl+C时正常退出,需要对相应的SIGINT信号进行捕捉,然后去做后续操作,网上看了一圈弄到最后都会报未定义的引用,然后在qt的issue中看到了解决办法:
MyDaemon.h:
#include "myProject.h"
class MyDaemon : public QObject
{
Q_OBJECT
public:
MyDaemon(QObject *parent = nullptr);
// Unix signal handlers.
static void intSignalHandler(int unused);
void setProj(myProject *proj) { p = proj; } //把主窗口的对象传过来以便进行操作
public slots:
// Qt signal handlers.
void handleSigInt();
private:
static int sigintFd[2];
QSocketNotifier *snInt;
myProject *p;
};
static int setup_unix_signal_handlers()
{
#if defined linux
struct sigaction interrupt;
interrupt.sa_handler = MyDaemon::intSignalHandler;
sigemptyset(&interrupt.sa_mask);
interrupt.sa_flags = 0;
interrupt.sa_flags |= SA_RESTART;
if (sigaction(SIGINT, &interrupt, 0))
return 1;
#endif
return 0;
}
MyDaemon.cpp:
#include "MyDaemon.h"
int MyDaemon::sigintFd[2]; //在cpp中还需要声明一下
MyDaemon::MyDaemon(QObject *parent) : QObject(parent) {
#if defined linux
if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sigintFd))
qFatal("Couldn't create INT socketpair");
snInt = new QSocketNotifier(sigintFd[1], QSocketNotifier::Read, this);
connect(snInt, SIGNAL(activated(int)), this, SLOT(handleSigInt()));
#endif
}
void MyDaemon::intSignalHandler(int unused) {
char a = 1;
::write(sigintFd[0], &a, sizeof(a));
}
void MyDaemon::handleSigInt() {
snInt->setEnabled(false);
char tmp;
::read(sigintFd[1], &tmp, sizeof(tmp));
//在此处做想要做的操作
p->close();
snInt->setEnabled(true);
}
main.cpp:
#include "MyDaemon.h"
#include "myProject.h"
int main() {
QApplication app(argc, argv);
myProject proj;
#if defined linux
setup_unix_signal_handlers();
MyDaemon daemon(nullptr);
daemon.setProj(&proj);
#endif
proj.show();
return app.exec();
}
这样就可以在终端ctrl+C时正常退出程序了