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
相关推荐
Jun62642 分钟前
QT(12)-制作lib库
开发语言·qt
努力努力再努力wz5 小时前
【内存管理与高并发内存池系列】从 mmap 到 malloc:文件映射、匿名映射与 glibc 内存分配机制详解
linux·c语言·数据结构·数据库·c++·qt·链表
JdSnE27zv5 小时前
Qt 操作SQLite数据库
数据库·qt·sqlite
小短腿的代码世界6 小时前
QtitanRibbon 深度解析:工业级Ribbon界面框架的架构设计与自定义扩展
qt·3d·架构
Drone_xjw8 小时前
qt配置项目样式表
开发语言·qt
niuniuyi~8 小时前
QT学习笔记
笔记·qt·学习
wearegogog1238 小时前
Qt触摸屏应用实例
qt
小短腿的代码世界8 小时前
Qt D-Bus深度解析:跨进程通信高级架构与源码实现
qt·架构·系统架构
luoyayun36112 小时前
Qt + FFmpeg 实战:音频静音段检测
qt·ffmpeg·音视频·静音段检测
小短腿的代码世界13 小时前
Qt Quick 3D场景导入与渲染架构深度解析:从USD到PBR材质的完整管线
qt·3d·架构