-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsingleapplication.cpp
More file actions
130 lines (114 loc) · 3.68 KB
/
Copy pathsingleapplication.cpp
File metadata and controls
130 lines (114 loc) · 3.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include "singleapplication.h"
#include "helpfunc.h"
#include <QtNetwork/QLocalSocket>
#include <QFileInfo>
#include <QMetaObject>
#define TIME_OUT 500
SingleApplication::SingleApplication(int &argc, char *argv[])
:QApplication(argc, argv),
w(NULL),
localserver(NULL),
isRunnings(false)
{
//取应用程序名作为localServer的名字
QString filePath = QApplication::applicationFilePath();
QByteArray bFilePath = filePath.toUtf8();
serverName = bFilePath.toBase64();
InitLocalConnection();
}
/*****************************************************************
* 检查是否已有一个实例在运行, true有实例运行, false没有实例运行.
******************************************************************/
bool SingleApplication::isRunning()
{
return isRunnings;
}
/*****************************************************************
* 通过socket通讯实现程序单实例运行,监听到新的连接时触发该函数.
******************************************************************/
void SingleApplication::NewLocalConnection()
{
QLocalSocket *localSocket = localserver->nextPendingConnection();
if(localSocket)
{
localSocket->waitForReadyRead(TIME_OUT * 2);
const QString message = QString::fromUtf8(localSocket->readAll()).trimmed();
delete localSocket;
if (message == QStringLiteral("toggle"))
{
ToggleWindow();
}
else
{
ActivateWindow();
}
}
}
QString SingleApplication::startupAction() const
{
if (isUos())
{
return QStringLiteral("toggle");
}
return arguments().contains(QStringLiteral("--toggle-window"))
? QStringLiteral("toggle")
: QStringLiteral("activate");
}
/*****************************************************************
* 通过socket通讯实现程序单实例运行,
* 初始化本地连接,如果连接不上server,则创建,否则退出
******************************************************************/
void SingleApplication::InitLocalConnection()
{
isRunnings = false;
QLocalSocket socket;
socket.connectToServer(serverName);
if(socket.waitForConnected(TIME_OUT))
{
isRunnings = true;
socket.write(startupAction().toUtf8());
socket.flush();
socket.waitForBytesWritten(TIME_OUT);
return;
}
//连接不上服务器,就创建一个
NewLocalServer();
}
/*****************************************************************
* 创建localserver
******************************************************************/
void SingleApplication::NewLocalServer()
{
localserver = new QLocalServer(this);
connect(localserver, &QLocalServer::newConnection, this, &SingleApplication::NewLocalConnection);
if(!localserver->listen(serverName))
{
// 此时监听失败,可能是程序崩溃时,残留进程服务导致的,移除
if(localserver->serverError() == QAbstractSocket::AddressInUseError)
{
localserver->removeServer(serverName);
localserver->listen(serverName); //重新监听
}
}
}
/*****************************************************************
* 激活主窗口
******************************************************************/
void SingleApplication::ActivateWindow()
{
if(w)
{
if (!QMetaObject::invokeMethod(w, "showMainWindow", Qt::DirectConnection))
{
w->show();
w->setWindowState(w->windowState() & ~Qt::WindowMinimized | Qt::WindowActive);
}
}
}
void SingleApplication::ToggleWindow()
{
if (w)
{
QMetaObject::invokeMethod(w, "sltHotKey", Qt::DirectConnection);
}
}