目前使QT运行一个实例有三种方式:
1.QSharedMemory
使用共享内存,当第二个进程启动时,判断内存区数据是否建立,如有,则退出; 这种方式有弊端,在程序发生崩溃时,未及时清除共享区数据,导致程序不能正常启动.
2. QtSingleApplication
使用QT扩展库QtSingleApplication,能很好的解决这个问题. 详见: http://qt.nokia.com/products/qt-addons/solutions-archive. 里面就是用的QLocalServer/QLocalSocket建立本地socket来判断实例是否存在
3. 利用QLocalServer实现
MyApplication.h
- class MyApplication:public QApplication
- {
- Q_OBJECT
- public:
- MyApplication(int argc,char **argv);
- bool isRunning();
- private slots:
- void newLocalConnection();
- private:
- QLocalServer *server;
- bool _isRunning;
- };
MyApplication.cpp
- MyApplication::MyApplication(int argc, char **argv):QApplication(argc,argv)
- {
- _isRunning=false;
- QCoreApplication::setApplicationName("localserver");
- QString serverName=QCoreApplication::applicationName();
- QLocalSocket socket;
- socket.connectToServer(serverName);
- if(socket.waitForConnected(500))
- {
- QTextStream stream(&socket);
- QStringList args=QCoreApplication::arguments();
- if(args.count()>1)
- {
- stream<<args.last();
- }else
- {
- stream<<QString();
- }
- stream.flush();
- qDebug()<<"Connected server,program will quit";
- socket.waitForBytesWritten();
- /**
- *qApp->quit(); 此代码是用来退出事件循环的;在构造函数中,事件循环
- *尚未启动,因此就无法退出. 最好就是设置标志判断在外部判断
- */
- _isRunning=true;
- return;
- }
- qDebug()<<"Can't connect to server,build a server";
- server=new QLocalServer(this);
- connect(server,SIGNAL(newConnection()),this,SLOT(newLocalConnection()));
- if(server->listen(serverName))
- {
- //防止程序崩溃时,残留进程服务,移除之
- if(server->serverError()==QAbstractSocket::AddressInUseError&&QFile::exists(server->serverName()))
- {
- QFile::remove(server->serverName());
- server->listen(serverName);
- }
- }
- }
- void MyApplication::newLocalConnection()
- {
- QLocalSocket *socket=server->nextPendingConnection();
- if(!socket)
- return;
- socket->waitForReadyRead(1000);
- //显示传入参数值
- QTextStream in(socket);
- QString vl;
- in>>vl;
- qDebug()<<"The value is: "<<vl;
- delete socket;
- }
- bool MyApplication::isRunning()
- {
- return _isRunning;
- }
主程序:
main.cpp
- int main(int argc,char **argv)
- {
- MyApplication app(argc,argv);
- if(app.isRunning())
- return 0;
- QLabel label;
- label.setText("Hello world");
- label.show();
- return app.exec();
- }
第一个实例: