目前使QT运行一个实例有三种方式:
1.QSharedMemory
使用共享内存,当第二个进程启动时,判断内存区数据是否建立,如有。则退出;这种方式有弊端,在程序发生崩溃时,未及时清除共享区数据,导致程序不能正常启动。
2. QtSingleApplication
使用QT扩展库QtSingleApplication,能很好的解决这个问题。里面就是用的QLocalServer/QLocalSocket建立本地socket来判断实例是否存在
3. 利用QLocalServer实现
代码如下:
single_application.h
1 #ifndef SINGLE_APPLICATION_H
2 #define SINGLE_APPLICATION_H
3
4 #include <QApplication>
5 #include <QLocalServer>
6
7 class SingleApplication:public QApplication
8 {
9 Q_OBJECT
10 public:
11 SingleApplication(int argc,char **argv);
12
13 bool isRunning();
14
15 private slots:
16 void newLocalConnection();
17
18 private:
19 QLocalServer *server;
20
21 bool _isRunning;
22 };
23
24 #endif // SINGLE_APPLICATION_H
single_application.cpp
1 #include <QLocalSocket>
2 #include "single_application.h"
3 4
5 SingleApplication::SingleApplication(int argc, char **argv):QApplication(argc,argv)
6 {
7 _isRunning=false;
8
9 QCoreApplication::setApplicationName("localserver");
10 QString serverName=QCoreApplication::applicationName();
11
12 QLocalSocket socket;
13 socket.connectToServer(serverName);
14
15 if(socket.waitForConnected(500))
16 {
17 QTextStream stream(&socket);
18 QStringList args=QCoreApplication::arguments();
19
20 if(args.count()>1)
21 {
22 stream<<args.last();
23 }else
24 {
25 stream<<QString();
26 }
27 stream.flush();
28 qDebug()<<"Connected server,program will quit";
29
30 socket.waitForBytesWritten();
31
32 /**
33 *qApp->quit(); 此代码是用来退出事件循环的;在构造函数中,事件循环
34 *尚未启动,因此就无法退出. 最好就是设置标志判断在外部判断
35 */
36
37
38 _isRunning=true;
39
40 return;
41 }
42
43 qDebug()<<"Can't connect to server,build a server";
44 server=new QLocalServer(this);
45 connect(server,SIGNAL(newConnection()),this,SLOT(newLocalConnection()));
46
47 if(!server->listen(serverName))
48 {
49 //防止程序崩溃时,残留进程服务,移除之
50 if(server->serverError()==QAbstractSocket::AddressInUseError)
51 {
52 QLocalServer::removeServer(serverName);
53 server->listen(serverName);54 }
55 }
56
57
58 }
59
60
61 void SingleApplication::newLocalConnection()
62 {
63 QLocalSocket *socket=server->nextPendingConnection();
64 if(!socket)
65 return;
66
67 socket->waitForReadyRead(1000);
68
69 //显示传入参数值
70 QTextStream in(socket);
71 QString vl;
72 in>>vl;
73 qDebug()<<"The value is: "<<vl;
74
75 delete socket;
76 }
77
78
79 bool SingleApplication::isRunning()
80 {
81 return _isRunning;
82 }
单例化的使用,将SingleApplication代替QApplication类。
main.c
1 #include "single_application.h"
2
3 int main(int argc, char *argv[])
4 {
5 SingleApplication a(argc, argv);
6 if(a.isRunning())
7 return 0;
8
9 MainWindow w;
10 w.show();
11
12 return a.exec();
13 }
注:因 使用QLocalServer的方式,需要在*.pro中添加“QT += network”,才使用LocalServer服务。
http://tcspecial.iteye.com/blog/1622353