Qt单一应用实例判断

原本项目中使用QSharedMemory的方法来判断当前是否已存在运行的实例,但在MacOS上,当程序异常崩溃后,QSharedMemory没有被正常销毁,导致应用程序无法再次被打开。

对此,Qt assistant中有相关说明:

摘抄 qt-solutions/qtsingleapplication at master · qtproject/qt-solutions (github.com) 实现了一个single application的类,记录下来:

main.cpp

cpp 复制代码
#include "mainwindow.h"
#include "singleapplication.h"

int main(int argc, char *argv[])
{
    CSingleApplication a(argc, argv);
    if (a.isRunning()) {
        return 0;
    }

    MainWindow w;
    w.show();
    a.setActivationWindow(&w);

    return a.exec();
}

singleapplication.cpp

cpp 复制代码
#include "singleapplication.h"
#include <QFileInfo>
#include <QLocalSocket>
#include <QLocalServer>
#include <QWidget>

CSingleApplication::CSingleApplication(int& argc, char** argv)
    : QApplication(argc, argv)
{
    m_strServerName = QFileInfo(QCoreApplication::applicationFilePath()).fileName();
    initLocalConn();
}

CSingleApplication::~CSingleApplication()
{

}

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

void CSingleApplication::setActivationWindow(QWidget* w)
{
    m_pActivateWin = w;
}

void CSingleApplication::initLocalConn()
{
    m_isRunning = false;

    QLocalSocket socket;
    socket.connectToServer(m_strServerName);
    if (socket.waitForConnected(200)) {
        m_isRunning = true;
        return;
    }

    createLocalServer();
}

void CSingleApplication::createLocalServer()
{
    m_pLocalServer = new QLocalServer(this);
    connect(m_pLocalServer, &QLocalServer::newConnection, this, &CSingleApplication::onNewConnection);
    if (!m_pLocalServer->listen(m_strServerName)) {
        if (QAbstractSocket::AddressInUseError == m_pLocalServer->serverError()) {
            QLocalServer::removeServer(m_strServerName);
            m_pLocalServer->listen(m_strServerName);
        }
    }
}

void CSingleApplication::activateWindow()
{
    if (nullptr != m_pActivateWin) {
        m_pActivateWin->show();
        m_pActivateWin->raise();
        m_pActivateWin->activateWindow();
    }
}

void CSingleApplication::onNewConnection()
{
    if (nullptr == m_pLocalServer) {
        return;
    }

    QLocalSocket* socket = m_pLocalServer->nextPendingConnection();
    if (nullptr != socket) {
        socket->waitForReadyRead(300);
        delete socket;
        activateWindow();
    }
}

singleapplication.h

cpp 复制代码
#ifndef CSINGLEAPPLICATION_H
#define CSINGLEAPPLICATION_H

#include <QApplication>

class QLocalServer;

class CSingleApplication : public QApplication
{
public:
    CSingleApplication(int& argc, char** argv);
    virtual ~CSingleApplication() override;

public:
    bool isRunning();
    void setActivationWindow(QWidget* w);

private:
    bool          m_isRunning = false;
    QWidget*      m_pActivateWin = nullptr;
    QString       m_strServerName;
    QLocalServer* m_pLocalServer = nullptr;

    void initLocalConn();
    void createLocalServer();
    void activateWindow();

private slots:
    void onNewConnection();
};

#endif // CSINGLEAPPLICATION_H
相关推荐
Hua-Jay30 分钟前
OpenCV联合C++/Qt 学习笔记(二十三)----图像校正及单目位姿估计
c++·笔记·qt·opencv·学习·计算机视觉
mirror_zAI1 小时前
C++ 仿 QQ 聊天室项目:Qt 客户端 + epoll 服务端 + Reactor 架构(含源码)
c++·qt·架构
Hua-Jay2 小时前
OpenCV联合C++/Qt 学习笔记(二十四)----差值法检测移动物体、稠密光流法跟踪移动物体及稀疏光流法跟踪移动物体
c++·笔记·qt·opencv·学习·计算机视觉
努力努力再努力wz3 小时前
【QT入门系列】QWidget 六大常用属性详解:windowOpacity、cursor、font、focus、toolTip 与 styleSheet
android·开发语言·数据结构·c++·qt·mysql·算法
程序leo源17 小时前
Qt窗口详解
开发语言·数据库·c++·qt·青少年编程·c#
我在人间贩卖青春19 小时前
重学Qt——事件处理
qt
小宋00119 小时前
QT中控件qss样式修改
开发语言·qt
yuechuji0011 天前
三、MPR(三平面重建)和三视图
qt
Hua-Jay1 天前
OpenCV联合C++/Qt 学习笔记(二十二)----相机模型与投影及单目相机标定
c++·笔记·qt·opencv·学习·计算机视觉
小短腿的代码世界1 天前
QCefView架构深度解析:从Chromium嵌入到Qt信号槽集成的完整技术链路
qt·架构