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
相关推荐
用户805533698033 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner3 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz8 天前
QML Hello World 入门示例
qt
xcyxiner11 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner11 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner12 天前
DicomViewer (添加模型类)3
qt
xcyxiner13 天前
DicomViewer (目录调整) 2
qt
xcyxiner13 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
桥田智能15 天前
桥田智能 QT-650S:面向白车身焊装的 800kg 重载快换解决方案
开发语言·qt·系统架构
森G15 天前
75、服务器源码解析---------云视频服务项目
linux·服务器·网络·c++·qt