- Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsingleapplication.cpp
More file actions
Latest commit
130 lines (114 loc) · 3.67 KB
/
Copy pathsingleapplication.cpp
File metadata and controls
130 lines (114 loc) · 3.67 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>
#defineTIME_OUT500
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没有实例运行.
******************************************************************/
boolSingleApplication::isRunning()
{
return isRunnings;
}
/*****************************************************************
* 通过socket通讯实现程序单实例运行,监听到新的连接时触发该函数.
******************************************************************/
voidSingleApplication::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())
{
returnQStringLiteral("toggle");
}
returnarguments().contains(QStringLiteral("--toggle-window"))
? QStringLiteral("toggle")
: QStringLiteral("activate");
}
/*****************************************************************
* 通过socket通讯实现程序单实例运行,
* 初始化本地连接,如果连接不上server,则创建,否则退出
******************************************************************/
voidSingleApplication::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
******************************************************************/
voidSingleApplication::NewLocalServer()
{
localserver = newQLocalServer(this);
connect(localserver, &QLocalServer::newConnection, this, &SingleApplication::NewLocalConnection);
if(!localserver->listen(serverName))
{
// 此时监听失败,可能是程序崩溃时,残留进程服务导致的,移除
if(localserver->serverError() == QAbstractSocket::AddressInUseError)
{
localserver->removeServer(serverName);
localserver->listen(serverName); //重新监听
}
}
}
/*****************************************************************
* 激活主窗口
******************************************************************/
voidSingleApplication::ActivateWindow()
{
if(w)
{
if (!QMetaObject::invokeMethod(w, "showMainWindow", Qt::DirectConnection))
{
w->show();
w->setWindowState(w->windowState() & ~Qt::WindowMinimized | Qt::WindowActive);
}
}
}
voidSingleApplication::ToggleWindow()
{
if (w)
{
QMetaObject::invokeMethod(w, "sltHotKey", Qt::DirectConnection);
}
}