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
相关推荐
zhmhbest3 小时前
Qt 全球峰会 2025:中国站速递 —— 技术中立,拥抱更大生态
开发语言·qt·系统架构
feiyangqingyun5 小时前
Qt实时绘制飞行轨迹/移动轨迹实时显示/带旋转角度/平滑移动/效果一级棒/地面站软件开发/无人机管理平台
qt·无人机·集群地面站
十五年专注C++开发8 小时前
Qt-VLC: 一个集成VLC的开源跨平台媒体播放库
开发语言·qt·媒体·libvlc·vlc-qt
Aevget12 小时前
QtitanNavigation助力能源数字化转型:打造清晰可控的系统导航体验
c++·qt·嵌入式·能源·界面控件·ui开发
寻找华年的锦瑟14 小时前
Qt Quick Application&&Qt Quick Application (compat)
开发语言·qt
上去我就QWER17 小时前
Qt中如何获取系统版本信息
开发语言·qt
十五年专注C++开发1 天前
Qt-Nice-Frameless-Window: 一个跨平台无边框窗口(Frameless Window)解决方案
开发语言·c++·qt
江公望1 天前
装了新的QtCreator17,没有用Qt5.12自带的QtCreator4,导致QtCreator17无法找到Qt5.12帮助文档
qt·qml
ctgu901 天前
PyQt5(八):ui设置为可以手动随意拉伸功能
开发语言·qt·ui
进击的大海贼1 天前
QT/C++ 消息定时管理器
开发语言·c++·qt