Qt实现应用单实例运行(2)-使用自定义类

1、.h文件

#ifndef SINGLEAPPLICATION_H
#define SINGLEAPPLICATION_H

#include <QObject>
#include <QApplication>
#include <QtNetwork/QLocalServer>
#include <QWidget>

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

2、.cpp文件

#include "SingleApplication.h"
#include <QtNetwork/QLocalSocket>
#include <QFileInfo>

#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); // <-- 重点
_localServer->listen(_serverName); // 再次监听
}
}
}

// 说明:
// 激活主窗口

void SingleApplication::_activateWindow() {
if(w) {
w->show();
w->raise();
w->activateWindow(); // 激活窗口
}
}

3、main文件

#include "vdpuMngUI.h"//我自己自定义的主窗口类
#include "SingleApplication.h"

int main(int argc, char *argv[])
{
SingleApplication app(argc, argv);
if (!app.isRunning())
{
VdpuMngUI *w = new VdpuMngUI;
app.w = w;
w->show();
return app.exec();
}
else
return 0;
}

备注:以上内容引自(经过了简单的修改):http://blog.csdn.net/yngaocn/article/details/43956327


4、说明

SingleApplication是一个自己写的类;派生于QApplication,使用方法很简单,将.h文件和.cpp文件添加到工程中(注意修改工程的.pro文件),并按照main.cpp修改自己的main文件即可。

本方法可以实现应用的单实例运行,但无法自动激活窗口。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lusirking

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值