#ifndef SINGLEAPPLICATION_H
#define SINGLEAPPLICATION_H
#include <QObject>
#include <QApplication>
#include <QWidget>
class QLocalServer;
class HiSingleApplication : public QApplication
{
Q_OBJECT
public:
HiSingleApplication(int &argc, char **argv);
bool isRunning(); //是否存在实例在运行中
QWidget *w; // MainWindow指针
QString getPath();
// 初始化本地连接
void initLocalConnection();
private slots:
// 有新连接时触发
void newLocalConnection();
private:
// 创建服务端
void newLocalServer();
// 激活窗口
void activateWindow();
bool event(QEvent *event);
private:
bool m_bRunning; // 是否有实例在运行
QLocalServer *m_pLocalServer; // 本地socket Server
QString m_qsServerName; // 服务名称
QString m_strPath = nullptr;
};
#endif
#include "HiSingleApplication.h"
#include <QtNetwork/QLocalSocket>
#include <QFileInfo>
#include <QLocalServer>
#include <QMessageBox>
#include <QIcon>
#include <QFileOpenEvent>
#define TIME_OUT (500) // 500ms
HiSingleApplication::HiSingleApplication(int &argc, char **argv)
: QApplication(argc, argv)
, w(NULL)
, m_bRunning(false)
, m_pLocalServer(NULL)
{
m_qsServerName = QFileInfo(QCoreApplication::applicationFilePath()).fileName();
initLocalConnection();
}
bool HiSingleApplication::isRunning()
{
return m_bRunning;
}
QString HiSingleApplication::getPath()
{
return m_strPath;
}
void HiSingleApplication::newLocalConnection()
{
QLocalSocket *socket = m_pLocalServer->nextPendingConnection();
if (socket)
{
socket->waitForReadyRead(2 * TIME_OUT);
delete socket;
activateWindow();
}
}
void HiSingleApplication::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 HiSingleApplication::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 HiSingleApplication::activateWindow()
{
if (w)
{
w->show();
w->raise();
w->activateWindow();
}
}
bool HiSingleApplication::event(QEvent *event)
{
if (event->type() == QEvent::FileOpen) {
QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(event);
m_strPath = openEvent->file();
}
return QApplication::event(event);
}