Qt——功能:实现应用程序单例

测试环境:win10、Qt Creator 4.11.1、5.14.2版本SDK

github:https://github.com/coldfirehello/QtDemo.git

参考链接:https://www.cnblogs.com/js2854/archive/2014/04/24/qt-single-app.html

 

实现思路:

1.运行第一个应用程序(如:test.exe)时,调用initLocalConnection()函数,判断是否可以连接已经监听了test.exe的服务器,如果无法连接,证明test.exe没有运行。此时创建一个本地服务器,并监听test.exe。

2.再一次运行时,调用initLocalConnection()函数,已经可以连接监听test.exe的本地服务。

3.进程运行标志设置为true,后续判断标志为true,退出应用程序。

 

直接上代码:

singleApplication.h
#ifndef SIGNALAPPLICATION_H
#define SIGNALAPPLICATION_H

#include <QApplication>
#include <QLocalServer>

class SignalApplication : public QApplication
{
    Q_OBJECT

public:
    SignalApplication(int &argc, char **argv, const QString& appName);
    ~SignalApplication();

    bool isRunning();

private slots:
    void newLocalConnection();

signals:
    void signalRunAgain();

private:
    bool m_isRunning;
    QLocalServer* m_localServer;
    QString m_appName;

private:
    //初始化本地连接
    void initLocalConnection();

    //创建服务端
    void newLocalServer();
};

#endif // SIGNALAPPLICATION_H


singleApplication.cpp
#include "singleApplication.h"
#include <QLocalSocket>
#include <QDebug>

#define TIME_OUT    500

SignalApplication::SignalApplication(int &argc, char **argv, const QString& appName)
    : QApplication(argc,argv),
      m_isRunning(false),
      m_localServer(nullptr),
      m_appName(appName)
{
    this->initLocalConnection();
}

SignalApplication::~SignalApplication()
{
    qDebug() << __FUNCTION__;
}

bool SignalApplication::isRunning()
{
    return m_isRunning;
}

void SignalApplication::newLocalConnection()
{
    qDebug() << __FUNCTION__;

    QLocalSocket* socket = m_localServer->nextPendingConnection();

    if(socket)
    {
        socket->waitForReadyRead(2*TIME_OUT);
        delete socket;

        //其它处理:如:读取启动参数

        emit signalRunAgain();
    }
}

void SignalApplication::initLocalConnection()
{
    qDebug() << __FUNCTION__;

    m_isRunning = false;

    QLocalSocket socket;
    socket.connectToServer(m_appName);

    if(socket.waitForConnected(TIME_OUT))
    {
        fprintf(stderr, "%s already running.\n", m_appName.toLocal8Bit().constData());
        m_isRunning = true;

        //其它处理,如:将启动参数发送到服务端
    }
    else
    {
        //连接不上服务器就创建一个
        newLocalServer();

        qDebug() << __FUNCTION__ << " new ";
    }
}

void SignalApplication::newLocalServer()
{
    m_localServer = new QLocalServer(this);

    if(m_localServer != nullptr)
    {
        qDebug() << __FUNCTION__;

        connect(m_localServer, SIGNAL(newConnection()), this, SLOT(newLocalConnection()));

        if(!m_localServer->listen(m_appName))
        {
            //此时监听失败,可能是程序崩溃时,残留进程服务导致的,移出
            if(m_localServer->serverError() == QAbstractSocket::AddressInUseError)
            {
                QLocalServer::removeServer(m_appName);  //移出
                m_localServer->listen(m_appName);
            }
        }
    }
}

 

测试代码:

#include "singleApplication.h"
#include <QApplication>
#include <QWidget>

int main(int argc, char *argv[])
{
    SignalApplication a(argc, argv, "singleApplication");

    a.setApplicationName("testSignalApplication");

    if(a.isRunning())
    {
        return EXIT_SUCCESS;
    }

    //开始正常运行
    QWidget w;
    w.show();

    return a.exec();
}

程序编译完毕后,使用git的命令行运行程序,结果如下:

再打开一个窗口,运行测试程序:

从图中可知,打印了singleApplication已经运行,证明判断出应用程序已经运行一个。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值