singleApplication.h
#ifndef SINGLEAPPLICATION_H
#define SINGLEAPPLICATION_H
#include <QObject>
#include <QApplication>
#include <QWidget>
class QLocalServer;
class SingleApplication : public QApplication {
Q_OBJECT
public:
SingleApplication(int &argc, char **argv);
bool isRunning(); //是否存在实例在运行中
QWidget *w; // MainWindow指针
private slots:
// 有新连接时触发
void newLocalConnection();
private:
// 初始化本地连接
void initLocalConnection();
// 创建服务端
void newLocalServer();
// 激活窗口
void activateWindow();
private:
bool m_bRunning; // 是否有实例在运行
QLocalServer *m_pLocalServer; // 本地socket Server
QString m_qsServerName; // 服务名称
};
#endif
#include "singleApplication.h"
#include <QtNetwork/QLocalSocket>
#include <QFileInfo>
#include <QLocalServer>
#include <QMessageBox>
#include <QIcon>
#define TIME_OUT (500) // 500ms
SingleApplication::SingleApplication(int &argc, char **argv)
: QApplication(argc, argv)
, w(NULL)
, m_bRunning(false)
, m_pLocalServer(NULL)
{
m_qsServerName = QFileInfo(QCoreApplication::applicationFilePath()).fileName();
initLocalConnection();
}
bool SingleApplication::isRunning()
{
return m_bRunning;
}
void SingleApplication::newLocalConnection()
{
QLocalSocket *socket = m_pLocalServer->nextPendingConnection();
if (socket)
{
socket->waitForReadyRead(2 * TIME_OUT);
delete socket;
activateWindow();
}
}
void SingleApplication::initLocalConnection()
{
m_bRunning = false;
QLocalSocket socket;
socket.connectToServer(m_qsServerName);
if (socket.waitForConnected(TIME_OUT))
{
fprintf(stderr, "%s already running.\n", m_qsServerName.toLocal8Bit().constData());
m_bRunning = true;
return;
}
newLocalServer();
}
void SingleApplication::newLocalServer()
{
m_pLocalServer = new QLocalServer(this);
connect(m_pLocalServer, SIGNAL(newConnection()), this, SLOT(newLocalConnection()));
if (!m_pLocalServer->listen(m_qsServerName))
{
if (m_pLocalServer->serverError() == QAbstractSocket::AddressInUseError)
{
QLocalServer::removeServer(m_qsServerName);
m_pLocalServer->listen(m_qsServerName);
}
}
}
void SingleApplication::activateWindow()
{
if (w)
{
w->show();
w->raise();
w->activateWindow();
}
}