返回顶部

收藏

让Qt应用程序只运行一个实例

更多

在实际应用中,我们经常需要让应用程序只有一个实例,再打开新的文档或者页面时,只是替换现在的窗口或者新打开一个标签,而不是重新启动一次应用程序。Qt中是否可以 做到这样呢,答案是肯定的,因为Qt本身可以直接调用系统API,肯定可以做到,但是我们希望找到一个跨平台的通用的解决方案。这就要用到Qt的QLocalSock et,QLocalServer类了,这两个类从接口上看和网络通信socket没有区别,但是它并不是真正的网络API,只是模仿了而已。这两个类在Unix/Li nux系统上采用Unix域socket实现,而在Windows上则采用有名管道(named pipe)来实现。既然是网络API,那么思路就很简单了,应用程序 启动时首先会去连一个服务器(这里通过应用程序的名字来标识,就像网络端口一样),如果连接失败,那么则自己是第一个实例,就创建这么一个服务器,否则将启动参数发送 到服务器,然后自动退出,而服务器会在收到通知以后进行处理。这些动作我想最好是放在创建Application实例后,因为Qt本身有很多操作没有Applicat ion实例是无法进行操作的(至少事件循环是在创立Application以后才能启动吧),因此最好的位置就是通过继承QApplicaiton或者QCoreAp plication自定义一个YourOwnApplication,然后在构造函数中进行,下面是一个示意。首先是YourOwnApplication构造函数:

cpp代码

QString serverName = QCoreApplication::applicationName();

QLocalSocket socket;
socket.connectToServer(serverName);

if (socket.waitForConnected(500)) { //如果能够连接得上的话,将参数发送到服务器,然后退出

    QTextStream stream(&socket);
    QStringList args = QCoreApplication::arguments();

    if (args.count() > 1)
        stream << args.last();
    else
        stream << QString();
    stream.flush();
    socket.waitForBytesWritten();
    qApp->quit();

    return;
}

//运行到这里,说明没有实例在运行,那么创建服务器。

m_localServer = new QLocalServer(this);

connect(m_localServer, SIGNAL(newConnection()),
            this, SLOT(newLocalSocketConnection())); //监听新到来的连接

if (!m_localServer->listen(serverName)) {
    if (m_localServer->serverError() == QAbstractSocket::AddressInUseError
            && QFile::exists(m_localServer->serverName())) { //确保能够监听成功
        QFile::remove(m_localServer->serverName());
        m_localServer->listen(serverName);
    }
}
// 这样就保证了新启动的程序在检测到有其他实例在运行时就会自动退出,
// 但是它发出的请求还没有被处理,
// 下面看一下处理函数,也就是前段代码中的newLocalSocketConnection()。

QLocalSocket *socket = m_localServer->nextPendingConnection();

if (!socket)
        return;

socket->waitForReadyRead(1000);
QTextStream stream(socket);
//其他处理

delete socket;
mainWindow()->raise();
mainWindow()->activateWindow(); //记得激活窗口哦

标签:qt

收藏

0人收藏

支持

0

反对

0

相关聚客文章
  1. 豆子 发表 2018-07-23 06:23:39 带有加密功能的 SQLite Qt 插件(v1.0)
  2. xinlu 发表 2018-07-05 08:33:52 使用匿名函数,简易地把同步转异步
  3. xinlu 发表 2018-06-28 11:43:30 Xperf与ETW脚本
  4. xinlu 发表 2018-06-24 10:32:09 预读处理
  5. 华华 发表 2018-06-12 00:21:49 LinuxStory 资讯速递 20180612 F2FS 针对 Linux 4.18 内核的更新已
  6. xinlu 发表 2018-04-19 20:54:07 cef的Qt的封装库及webrtc的测试
  7. xinlu 发表 2018-04-19 04:32:14 带动态链接库的启动脚本
  8. xinlu 发表 2018-03-13 09:57:54 Apple相关离线下载
  9. xinlu 发表 2018-02-12 04:28:40 Qt的国际语言怎么用
  10. xinlu 发表 2018-02-11 09:50:08 Qt的Centos7安装编译错误
  11. eryar 发表 2018-02-05 14:50:00 Qt源码编译
  12. 豆子 发表 2017-05-08 15:18:21 Qt Creator 源码学习 09:IPlugin

发表评论