Qt 实现应用程序单实例运行 您所在的位置:网站首页 qt如何退出 Qt 实现应用程序单实例运行

Qt 实现应用程序单实例运行

2023-05-29 05:56| 来源: 网络整理| 查看: 265

一、实现方案

目前使 Qt 运行一个实例有如下几种方式:

1.QSharedMemory

使用共享内存,当第二个进程启动时,判断内存区数据是否建立,如有,则退出;这种方式有弊端,在程序发生崩溃时,未及时清除共享区数据,导致程序不能正常启动。

2.文件锁

在程序运行的时候就在目录下创建一个文件,当程序运行时就判断这个文件是否存在,如果存在说明程序已经在运行。其本质与 QSharedMemory 相同。

3.利用QLocalServer 要用到Qt的QLocalSocket,QLocalServer类,这两个类从接口上看和网络通信socket没有区别,但是它并不是真正的网络API,只是模仿了而已。这两个类在Unix/Linux系统上采用Unix域socket实现,而在Windows上则采用有名管道(named pipe)来实现4.QtSingleApplication 使用 Qt 扩展库 QtSingleApplication,能很好的解决这个问题。 QSingleApplication 是 Qt 提供的一个 solution ,它不包含在 Qt 的 library 中。遵循 LGPL 协议。Qt 欢迎里面有例子。

二、实现代码

下面给出了 LocalServer 方式的实现代码。

SingleApplication.h:

#ifndef SINGLEAPPLICATION_H #define SINGLEAPPLICATION_H #include #include #include #include class SingleApplication : public QApplication { Q_OBJECT public: SingleApplication(int &argc, char **argv); bool isRunning(); // 是否已經有实例在运行 QWidget *w; // MainWindow指针 private slots: // 有新连接时触发 void _newLocalConnection(); private: // 初始化本地连接 void _initLocalConnection(); // 创建服务端 void _newLocalServer(); // 激活窗口 void _activateWindow(); bool _isRunning; // 是否已經有实例在运行 QLocalServer *_localServer; // 本地socket Server QString _serverName; // 服务名称 }; #endif // SINGLEAPPLICATION_H

SingleApplication.cpp:

#include "SingleApplication.h" #include #include #define TIME_OUT (500) // 500ms SingleApplication::SingleApplication(int &argc, char **argv) : QApplication(argc, argv) , w(NULL) , _isRunning(false) , _localServer(NULL) { // 取应用程序名作为LocalServer的名字 _serverName = QFileInfo(QCoreApplication::applicationFilePath()).fileName(); _initLocalConnection(); } // 说明: // 检查是否已經有一个实例在运行, true - 有实例运行, false - 没有实例运行 bool SingleApplication::isRunning() { return _isRunning; } // 说明: // 通过socket通讯实现程序单实例运行,监听到新的连接时触发该函数 void SingleApplication::_newLocalConnection() { QLocalSocket *socket = _localServer->nextPendingConnection(); if(socket) { socket->waitForReadyRead(2*TIME_OUT); delete socket; // 其他处理,如:读取启动参数 _activateWindow(); } } // 说明: // 通过socket通讯实现程序单实例运行, // 初始化本地连接,如果连接不上server,则创建,否则退出 void SingleApplication::_initLocalConnection() { _isRunning = false; QLocalSocket socket; socket.connectToServer(_serverName); if(socket.waitForConnected(TIME_OUT)) { fprintf(stderr, "%s already running.\n", _serverName.toLocal8Bit().constData()); _isRunning = true; // 其他处理,如:将启动参数发送到服务端 return; } //连接不上服务器,就创建一个 _newLocalServer(); } // 说明: // 创建LocalServer void SingleApplication::_newLocalServer() { _localServer = new QLocalServer(this); connect(_localServer, SIGNAL(newConnection()), this, SLOT(_newLocalConnection())); if(!_localServer->listen(_serverName)) { // 此时监听失败,可能是程序崩溃时,残留进程服务导致的,移除之 if(_localServer->serverError() == QAbstractSocket::AddressInUseError) { QLocalServer::removeServer(_serverName); // listen(_serverName); // 再次监听 } } } // 说明: // 激活主窗口 void SingleApplication::_activateWindow() { if(w) { w->show(); w->raise(); w->activateWindow(); // 激活窗口 } }

调用示例:

#include "MainWindow.h" #include "SingleApplication.h" int main(int argc, char *argv[]) { SingleApplication a(argc, argv); if(!a.isRunning()) { MainWindow w; a.w = &w; w.show(); return a.exec(); } return 0; }



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有