让QT只运行一个实例

      目前使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();
}

  

 

   第一个实例:

  让QT只运行一个实例_第1张图片

 

 让QT只运行一个实例_第2张图片

你可能感兴趣的:(QLocalSocket,QLocalServer,QT单个实例)