测试环境:win10、Qt Creator 4.11.1、5.14.2版本SDK
github:https://github.com/coldfirehello/QtDemo.git
参考链接:https://www.cnblogs.com/js2854/archive/2014/04/24/qt-single-app.html
实现思路:
1.运行第一个应用程序(如:test.exe)时,调用initLocalConnection()函数,判断是否可以连接已经监听了test.exe的服务器,如果无法连接,证明test.exe没有运行。此时创建一个本地服务器,并监听test.exe。
2.再一次运行时,调用initLocalConnection()函数,已经可以连接监听test.exe的本地服务。
3.进程运行标志设置为true,后续判断标志为true,退出应用程序。
直接上代码:
singleApplication.h
#ifndef SIGNALAPPLICATION_H
#define SIGNALAPPLICATION_H
#include <QApplication>
#include <QLocalServer>
class SignalApplication : public QApplication
{
Q_OBJECT
public:
SignalApplication(int &argc, char **argv, const QString& appName);
~SignalApplication();
bool isRunning();
private slots:
void newLocalConnection();
signals:
void signalRunAgain();
private:
bool m_isRunning;
QLocalServer* m_localServer;
QString m_appName;
private:
//初始化本地连接
void initLocalConnection();
//创建服务端
void newLocalServer();
};
#endif // SIGNALAPPLICATION_H
singleApplication.cpp
#include "singleApplication.h"
#include <QLocalSocket>
#include <QDebug>
#define TIME_OUT 500
SignalApplication::SignalApplication(int &argc, char **argv, const QString& appName)
: QApplication(argc,argv),
m_isRunning(false),
m_localServer(nullptr),
m_appName(appName)
{
this->initLocalConnection();
}
SignalApplication::~SignalApplication()
{
qDebug() << __FUNCTION__;
}
bool SignalApplication::isRunning()
{
return m_isRunning;
}
void SignalApplication::newLocalConnection()
{
qDebug() << __FUNCTION__;
QLocalSocket* socket = m_localServer->nextPendingConnection();
if(socket)
{
socket->waitForReadyRead(2*TIME_OUT);
delete socket;
//其它处理:如:读取启动参数
emit signalRunAgain();
}
}
void SignalApplication::initLocalConnection()
{
qDebug() << __FUNCTION__;
m_isRunning = false;
QLocalSocket socket;
socket.connectToServer(m_appName);
if(socket.waitForConnected(TIME_OUT))
{
fprintf(stderr, "%s already running.\n", m_appName.toLocal8Bit().constData());
m_isRunning = true;
//其它处理,如:将启动参数发送到服务端
}
else
{
//连接不上服务器就创建一个
newLocalServer();
qDebug() << __FUNCTION__ << " new ";
}
}
void SignalApplication::newLocalServer()
{
m_localServer = new QLocalServer(this);
if(m_localServer != nullptr)
{
qDebug() << __FUNCTION__;
connect(m_localServer, SIGNAL(newConnection()), this, SLOT(newLocalConnection()));
if(!m_localServer->listen(m_appName))
{
//此时监听失败,可能是程序崩溃时,残留进程服务导致的,移出
if(m_localServer->serverError() == QAbstractSocket::AddressInUseError)
{
QLocalServer::removeServer(m_appName); //移出
m_localServer->listen(m_appName);
}
}
}
}
测试代码:
#include "singleApplication.h"
#include <QApplication>
#include <QWidget>
int main(int argc, char *argv[])
{
SignalApplication a(argc, argv, "singleApplication");
a.setApplicationName("testSignalApplication");
if(a.isRunning())
{
return EXIT_SUCCESS;
}
//开始正常运行
QWidget w;
w.show();
return a.exec();
}
程序编译完毕后,使用git的命令行运行程序,结果如下:
再打开一个窗口,运行测试程序:
从图中可知,打印了singleApplication已经运行,证明判断出应用程序已经运行一个。