有些项目只允许启动一个exe,因此需要处理一下,Qt自己给了一个QSingleApplication的例子
使用QLocalServer创建一个服务,然后每次启动时,判断是否已经有连接上,具体代码如下
#ifndef SINGLE_APPLICATION_H
#define SINGLE_APPLICATION_H
#include <QApplication>
class QLocalServer;
class QSingleApplication : public QApplication
{
Q_OBJECT
public:
QSingleApplication(int argc, char **argv);
// 判断进程是否存在
bool isRunning();
private slots:
void newLocalConnection();
private:
QLocalServer *pServer;
bool bRunning;
};
#endif // SINGLE_APPLICATION_H
#include "qsingleapplication.h"
#include <QLocalSocket>
#include <QLocalServer>
#include <QFile>
#include <QTextStream>
QSingleApplication::QSingleApplication(int argc, char **argv)
: QApplication(argc, argv),
bRunning(false)
{
QCoreApplication::setApplicationName("BPaaa");
QCoreApplication::setApplicationVersion("VERSION_STRING");
QCoreApplication::setOrganizationName("BPabc");
QCoreApplication::setOrganizationDomain("https://github.com");
QString strServerName = QCoreApplication::organizationName() + QCoreApplication::applicationName();
QLocalSocket socket;
socket.connectToServer(strServerName);
if (socket.waitForConnected(500))
{
QTextStream stream(&socket);
QStringList args = QCoreApplication::arguments();
QString strArg = (args.count() > 1) ? args.last() : "";
stream << strArg;
stream.flush();
qDebug() << "Have already connected to server.";
socket.waitForBytesWritten();
bRunning = true;
}
else
{
// 如果不能连接到服务器,则创建一个
pServer = new QLocalServer(this);
connect(pServer, SIGNAL(newConnection()), this, SLOT(newLocalConnection()));
if (pServer->listen(strServerName))
{
// 防止程序崩溃,残留进程服务,直接移除
if ((pServer->serverError() == QAbstractSocket::AddressInUseError) && QFile::exists(pServer->serverName()))
{
QFile::remove(pServer->serverName());
pServer->listen(strServerName);
}
}
}
}
void QSingleApplication::newLocalConnection()
{
QLocalSocket *pSocket = pServer->nextPendingConnection();
if (pSocket != nullptr)
{
pSocket->waitForReadyRead(1000);
QTextStream in(pSocket);
QString strValue;
in >> strValue;
qDebug() << QString("The value is: %1").arg(strValue);
delete pSocket;
pSocket = nullptr;
}
}
bool QSingleApplication::isRunning()
{
return bRunning;
}
使用方式如下
int main(int argc, char *argv[])
{
// QApplication a(argc, argv); //替换掉这一句
QSingleApplication a(argc, argv);
if(a.isRunning())
{
return 0;
}
......
......
return a.exec();
}
也有用QShareMemory处理的,在main.cpp中加入如下语句。
QSystemSemaphore sema("AA",1, QSystemSemaphore::Open);
sema.acquire();// 在临界区操作共享内存 SharedMemory
QSharedMemory mem("AAAAA");// 全局对象名
if (!mem.create(1))// 如果全局对象已存在则退出
{
sema.release(); // 如果是 Unix 系统,会自动释放。
return 0;
}