在实际应用中,我们经常需要让应用程序只有一个实例,再打开新的文档或者页面时,只是替换现在的窗口或者新打开一个标签,而不是重新启动一次应用程序。Qt中是否可以做到这样呢,答案是肯定的,因为Qt本身可以直接调用系统API,肯定可以做到,但是我们希望找到一个跨平台的通用的解决方案。

这就要用到Qt的QLocalSocket,QLocalServer类了,这两个类从接口上看和网络通信socket没有区别,但是它并不是真正的网络API,只是模仿了而已。这两个类在Unix/Linux系统上采用Unix域socket实现,而在Windows上则采用有名管道(named pipe)来实现。

既然是网络API,那么思路就很简单了,应用程序启动时首先会去连一个服务器(这里通过应用程序的名字来标识,就像网络端口一样),如果连接失败,那么则自己是第一个实例,就创建这么一个服务器,否则将启动参数发送到服务器,然后自动退出,而服务器会在收到通知以后进行处理。

这些动作我想最好是放在创建Application实例后,因为Qt本身有很多操作没有Application实例是无法进行操作的(至少事件循环是在创立Application以后才能启动吧),因此最好的位置就是通过继承QApplicaiton或者QCoreApplication自定义一个YourOwnApplication,然后在构造函数中进行,下面是一个示意。

首先是YourOwnApplication构造函数:

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应用程序单实例化的更多相关文章

  1. Qt实现应用程序单实例运行--LocalServer方式

    使Qt应用程序能够单实例运行的典型实现方法是使用共享内存实现.该方法实现简单,代码简洁. 但有一个致命缺陷:共享内存(QSharedMemory)实现的单程序运行,当运行环境是UNIX时,并且程序不幸 ...

  2. qt 共享内存 单例

        QT 进程间通信之古老的方法(内存共享)     让QT只运行一个实例     以上两篇文章中分别讲述了QSharedMemory的不同作用,第一篇讲了进程间通信,第二篇讲述了怎么让应用程序只 ...

  3. 【Qt开发】QT样式表单 qss的样式优化

    QT样式表单 QT的样式表单允许我们在对程序不做任何代码上的更改的情况下轻松改变应用程序的外观. 其思想来源于网页设计中的CSS,即可以将功能设计和美学设计分开. 它的语法和概念和HTML CSS也是 ...

  4. Qt应用程序图标设置

    Qt应用程序图标设置 本文仅仅适用于windows下,linux等不适用. 下面说的图标,指的是程序文件的图标,而不是托盘图标或者说运行时任务栏的图标(任务栏和程序窗口的图标在windows/linu ...

  5. 报表控件NCReport教程:集成NCReport到Qt应用程序中

    NCReport是一款轻量级.快速.多平台.简单易用的基于Qt toolkit的C++编写的报表解决方案,目前主要包括报表渲染库和报表设计器GUI应用程序. 但是好多使用NCReport控件的朋友都不 ...

  6. QT添加程序图标及窗口图标

    程序图标 材料准备 图标文件:*.ico文件,存放在源文件同一目录下,如"myapp.ico" 写入图标 向*.pro文件中,独立一行写入"RC_ICONS = *.ic ...

  7. Ubuntu下QT控制台程序无法运行的解决方案以及XTerm的配置方法

    Ubuntu下QT控制台程序无法运行的解决方案以及XTerm的配置方法 最近由于老师要求要在Ubuntu下QT上进程多线程服务器的开发,虽然只是单纯的调用qt的network模块,但是为了避免麻烦,我 ...

  8. Linux下Qt应用程序的发布(使用LDD命令查看所有依赖的库文件)

    最近一直在学习Qt,用Qt写了一个程序,但是不知道怎么发布,网上说的都是在windows下怎么发布Qt应用程序,但是,在windows下Qt应用程序依赖的库文件与linux下的名字不同.于是,我就想到 ...

  9. 让你的 Qt 桌面程序看上去更加 native(一共六篇)

    <让你的 Qt 桌面程序看上去更加 native>是一个系列文章.在这个系列中,你将会了解到如何让你的 Qt 桌面应用程序看上去更加 native.这里,我假设你已经清楚如何使用 Qt 编 ...

随机推荐

  1. cocos2dx九宫图使用方法

    九宫格Sprite: itemBg = Scale9Sprite::create("pop/achieve_itembg.png");if(!itemBg)return false ...

  2. Lua在Windows下的配置、安装、运行

    Windows下安装.运行Lua! 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1↓ 进入Lua官网:h ...

  3. Java之从头开始编写简单课程信息管理系统

    编写简单的课程管理系统对于新手并不友好,想要出色的完成并不容易以下是我的一些经验和方法 详情可参考以下链接: https://www.cnblogs.com/dream0-0/p/10090828.h ...

  4. 回收机制GC

    .NET 之 垃圾回收机制GC 一.GC的必要性 1.应用程序对资源操作,通常简单分为以下几个步骤:为对应的资源分配内存 → 初始化内存 → 使用资源 → 清理资源 → 释放内存. 2.应用程序对资源 ...

  5. [codeforces Mail.Ru Cup 2018 Round 1 D][ xor 操作]

    http://codeforces.com/contest/1054/problem/D 题目大意:一个序列a1 a2...an,可以对若干个元素进行取反,使所得的新序列异或和为0的区间个数最多. 题 ...

  6. Spring——使用自定义标签

    文章内容参考了<Spring源码深度解析>一书.自己照着书中内容做了一遍,不懂的地方以及采坑的地方会在文中记录. 推荐一篇post,关于Spring配置文件的命名空间: https://w ...

  7. SpringBoot企业级博客开发

    1.springboot生成项目 PS : 进入项目,输入gradle build,生成build文件夹:  然后进入libs有jar,使用java jar进行运行项目 PS: 这个项目没有准守res ...

  8. 使用VUE搭建tab标签组件

    Vue2.0 多 Tab切换组件简单封装,满足自己简单的功能,可以直接拿去使用! 首先上效果图: 功能简单介绍: 1.支持tab切换 2.支持tab定位 3.支持tab自动化 仿React多Tab实现 ...

  9. Java基础一(开发环境、注释、关键字、标识符、数据)

    1.Java开发环境搭建2.HelloWorld案例3.注释.关键字.标识符4.数据(数据类型.常量) ###01java语言概述 * A: java语言概述 * a: Java是sun公司开发的一门 ...

  10. nginx unit nodejs 模块试用(续)

      最新(应该是18 年了)nginx unit 发布了新的版本,对于nodejs 的支持有很大的改进,上次测试过,问题还是 比较多,这次使用新版本在测试下对于nodejs 的支持,以及以前block ...