Qt运行一个实例进程

在开发项目的工程中,我们经常希望只运行一个相同的Qt实例进程。当然也可以像类似QQ那样,同时登录多个不同的账号!为了避免这个问题,介绍以下几种用法,每一个解决方案都适用于特定的情况,所以必须尝试和适用合适的解决方案。


一:使用QLocalSocket

    方式:首先一个新的实例启动时,将尝试连接到同一个本地服务器,如果连接失败,则表示第一个实例进程,创建一个本地服务器。否则,进行退出。

  1. void MainWidget::initLocalConnection()  
  2. {  
  3.     is_running = false;  
  4.     QCoreApplication::setApplicationName("localserver");  
  5.     QString serverName = QCoreApplication::applicationName();  
  6.     QLocalSocket socket;  
  7.     socket.connectToServer(serverName);  
  8.     if(socket.waitForConnected(500))  
  9.     {  
  10.         is_running = true;  
  11.         return;  
  12.     }  
  13.       
  14.     //连接不上服务器,就创建一个   
  15.     server = new QLocalServer(this);  
  16.     connect(server, SIGNAL(newConnection()), this, SLOT(newLocalConnection()));  
  17.     if(server->listen(serverName))  
  18.     {  
  19.         //防止程序崩溃时,残留进程服务,移除之   
  20.         if(server->serverError() == QAbstractSocket::AddressInUseError && QFile::exists(server->serverName()))  
  21.         {  
  22.             QFile::remove(server->serverName());  
  23.             server->listen(serverName);  
  24.         }  
  25.     }  
  26. }  
  27.   
  28.   
  29. void MainWidget::newLocalConnection()  
  30. {  
  31.     QLocalSocket *socket = server->nextPendingConnection();  
  32.     if(!socket)  
  33.         return;  
  34.     socket->waitForReadyRead(1000);  
  35.     delete socket;  
  36. }  
  37.   
  38.   
  39. bool MainWidget::isRunning()  
  40. {  
  41.     return is_running;  
  42. }   
void MainWidget::initLocalConnection()
{
    is_running = false;
    QCoreApplication::setApplicationName("localserver");
    QString serverName = QCoreApplication::applicationName();
    QLocalSocket socket;
    socket.connectToServer(serverName);
    if(socket.waitForConnected(500))
    {
        is_running = true;
        return;
    }
    
    //连接不上服务器,就创建一个
    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 MainWidget::newLocalConnection()
{
    QLocalSocket *socket = server->nextPendingConnection();
    if(!socket)
        return;
    socket->waitForReadyRead(1000);
    delete socket;
}


bool MainWidget::isRunning()
{
    return is_running;
} 

main.cpp中:

  1. MainWidget main_widget;  
  2. if(!main_widget.isRunning())  
  3. {  
  4.     main_widget.showNormal();  
  5.     main_widget.raise();  
  6.     main_widget.activateWindow();  
  7.       
  8.     return app.exec();  
  9. }  
MainWidget main_widget;
if(!main_widget.isRunning())
{
    main_widget.showNormal();
    main_widget.raise();
    main_widget.activateWindow();
    
    return app.exec();
}

1、创建一个QLoaclSocket,连接服务器
2、创建一个QLocalServer,并监听连接
3、启动应用程序之间,检查有多少个连接,如果至少有一个,意味着打开了一个应用程序,则不再打开另一个。


二:使用QSharedMemory 
    方式:先创建一个共享内存,然后在每一个应用程序开始运行之前进行检查是否可以创建一个具有相同unique_id的共享内存,如果不能,则表示创建了实例正在运行。

  1. QSharedMemory shared_memory;  
  2. shared_memory.setKey(unique_id);  
  3. if(shared_memory.attach())  
  4. {  
  5.     return 0;  
  6. }  
  7.   
  8.   
  9. if(shared_memory.create(1))  
  10. {  
  11.     MainWidget main_widget;  
  12.     main_widget.showNormal();  
  13.     main_widget.raise();  
  14.     main_widget.activateWindow();  
  15.   
  16.   
  17.     return app.exec();  
  18. }  
QSharedMemory shared_memory;
shared_memory.setKey(unique_id);
if(shared_memory.attach())
{
    return 0;
}


if(shared_memory.create(1))
{
    MainWidget main_widget;
    main_widget.showNormal();
    main_widget.raise();
    main_widget.activateWindow();


    return app.exec();
}


另一种方法:http://blog.youkuaiyun.com/yangxiao_0203/article/details/9622781

 

附:方法二main.cpp中的完整代码示例

  1. //mian.cpp   
  2. #include "mainwindow.h"   
  3. #include <QApplication>   
  4. #include <QSharedMemory>   
  5. #include <QMessageBox>   
  6.   
  7. int main(int argc, char *argv[])  
  8. {  
  9.     QApplication a(argc, argv);  
  10.   
  11.     QSharedMemory shared_memory;  
  12.     shared_memory.setKey("THISISATEST00594869");  
  13.     if(shared_memory.attach())  
  14.     {  
  15.         QMessageBox::information(0,"Information","This program is running already.",QMessageBox::Yes);  
  16.         return 0;  
  17.     }  
  18.   
  19.   
  20.     if(shared_memory.create(1))  
  21.     {  
  22.         MainWindow w;  
  23.         w.show();  
  24.   
  25.         return a.exec();  
  26.     }  
  27.     return -1;  
  28. }  
//mian.cpp
#include "mainwindow.h"
#include <QApplication>
#include <QSharedMemory>
#include <QMessageBox>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QSharedMemory shared_memory;
    shared_memory.setKey("THISISATEST00594869");
    if(shared_memory.attach())
    {
        QMessageBox::information(0,"Information","This program is running already.",QMessageBox::Yes);
        return 0;
    }


    if(shared_memory.create(1))
    {
        MainWindow w;
        w.show();

        return a.exec();
    }
    return -1;
}



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值