http://blog.sina.com.cn/s/blog_6343941a0100nk2x.html

可以达到的目的:

1、应用只启动一个实例,依赖于QtNetwork模块

2、启动时向另一个实例通信

下载地址:http://qt.gitorious.org/qt-solutions/qt-solutions/archive-tarball/master

解压开后,将里面的qtsingleapplication目录拷贝到项目的源码目录中,然后修改项目的.pro文件,加入下面一行代码

==============

include(../qtsingleapplication/src/qtsingleapplication.pri)

==============

修改main.cpp文件,加入头文件

#include <QtSingleApplication>

main函数实现:

===================================

QtSingleApplication app(argc, argv);

if (app.isRunning())

{

app.sendMessage("raies");

return EXIT_SUCCESS;

}

........

QMainWindow w;

app.setActivationWindow(&w);

.......

===================================

为了使一个应用程序在同一时间只运行一个实例,需要用某种方法在程序启动时,检测是否已有正在运行的实例,如果有,则将本次启动的参数传递给前一个实例(例如需要打开的文档的路径),如果没有,则正常启动。


实现的方法有多种:
1. 用Windows API创建一个互斥量:
 #include <windows.h>

 int main(int argc, char *argv[])
{
    QApplication a(argc, argv);     HANDLE hMutex = CreateMutex(NULL, TRUE, L"YourApp");     // 创建一个互斥量来保证只运行一个实例
    if(hMutex != NULL)
    {
        if(GetLastError() == ERROR_ALREADY_EXISTS)
        {
            QMessageBox::critical(qApp->activeWindow(), QObject::tr("An instance of this application has been run!"), QObject::tr("Only one instance can be run at a time!"));
            return 1;
        }
    }

    ...           // 以下是正常启动代码
}
注:如果保险起见,CreateMutex()中的字符串应该用一个GUID来保证其唯一性,Visual Studio中有一个生成GUID的工具,菜单“工具”->“创建GUID”,选择合适的定义形式,创建并拷贝到剪贴板即可。



此方法的缺点:1.使用了Windows API,不能跨平台;2.不能自动激活前一个实例的窗口。

2. 每次启动时用Windows API枚举进程,同时在第一次运行时用SetProp()函数给当前窗口设置属性,这样下次启动时,在枚举的进程中查找具有这个属性的窗口,若找到,说明已有实例在运行,将该实例的窗口激活;若未找到则正常启动。
此方法客服了前一方法的第2个缺点,但过于依赖Windows API函数(似乎还是MFC函数,对Qt程序好像不可行)。有兴趣的可以照这个链接里的代码试试

3. 利用QLocalSocket和QLocalServer,基本的思路是:
应用程序启动时首先尝试去连接一个QLocalServer,如果连接失败,说明自己是第一个实例,于是创建这么一个QLocalServer,否则将启动参数发送给QLocalServer然后退出。第一个实例的QLocalServer在收到后面启动的实例发来的参数时可以进行处理(例如激活第一个实例的窗口)。这个链接里有详细的示例代码供参考。

注:使用QLocalSocket和QLocalServer时,需要把QtNetwork库包含在项目文件中;

4. 用Qt Solutions里提供的QtSingleApplication类(最简单的方法,推荐)
ftp://ftp.qt.nokia.com/qt/solutions/lgpl/ 下载QtSingleApplication的源码包,解压缩后按照INSTALL.TXT里的说明进行配置和编译,我选择编译成动态库,这样下次再用,只需引用头文件和lib文件即可,比较方便。

用法很简单,只需把原来main()里的QApplication对象换成QtSingleApplication对象,调用一下isRunning()方法进行判断即可。
 // 原来的代码
int main(int argc, char **argv)
{
    QApplication app(argc, argv);     MyMainWidget mmw;     mmw.show();
    return app.exec();
} // 修改后的代码
int main(int argc, char **argv)
{
    QtSingleApplication app(argc, argv);     if (app.isRunning())
        return 0;     MyMainWidget mmw;
    mmw.show();
    return app.exec();
}
注1:QtSingleApplication的实现方法基本上也是利用QLocalServer和QLocalSocket,所以同样依赖于QtNetwork库;
注2:以上代码只展示了QtSingleApplication最简单的用法,这个类还有更多用法,请参考源码包中带的范例和文档。

QtSingleApplication的几种用法(直接使用源码,编译成动态库等)可以参考这个链接:Qt程序只运行一个实

如何用Qt写一个同一时间只能运行一个实例的应用程序的更多相关文章

  1. centos7 搭建docker内运行rabbitmq,然后再镜像ha方案的完全教程,暂时一个宿主机只能运行一个docker的rabbitmq,但是集群 ha都正常

    1.安装centos7.x,配置好网络2.因为docker需要比较高版本的内核,比如使用overlayfs作为默认docker文件系统要3.18,所以先升级内核到3.18以上版本,能直接过4是最佳了检 ...

  2. Oracle 远程访问配置 在 Windows Forms 和 WPF 应用中使用 FontAwesome 图标 C#反序列化XML异常:在 XML文档(0, 0)中有一个错误“缺少根元素” C#[Win32&WinCE&WM]应用程序只能运行一个实例:MutexHelper Decimal类型截取保留N位小数向上取, Decimal类型截取保留N位小数并且不进行四舍五入操作

    Oracle 远程访问配置   服务端配置 如果不想自己写,可以通过 Net Manager 来配置. 以下配置文件中的 localhost 改为 ip 地址,否则,远程不能访问. 1.网络监听配置 ...

  3. 让powershell同时只能运行一个脚本(进程互斥例子)

    powershell,mutex,互斥,进程互斥,脚本互斥 powershell脚本互斥例子,在powershell类别文章中,声明原创唯一. powershell 传教士 原创文章 2016-07- ...

  4. 同一个PC只能运行一个应用实例(考虑多个用户会话情况)

    原文:同一个PC只能运行一个应用实例(考虑多个用户会话情况) class Program { private static Mutex m; [STAThread] static void Main( ...

  5. 让程序同时只能运行一个C++ Builder实现(转)

    源:让程序同时只能运行一个 很多人都讨论过这个问题, 这里用Victor串口控件里面现成的共享内存功能来实现. 当程序运行第二次时只是激活第一次运行的窗口, 而不是再运行一个程序. 需要在主程序里实现 ...

  6. kubernetes 每个node上只能运行一个副本DaemonSet

    每个node上只能运行一个副本: apiVersion: extensions/v1beta1 kind: DaemonSet #使用DaemonSet的方式运行 metadata: name: ku ...

  7. C# WINFORM判断程序是否运行,且只能运行一个实例(转)

    判断程序是否已经运行,使程序只能运行一个实例有很多方法,下面记录两种, 方法1:线程互斥 static class Program { private static System.Threading. ...

  8. winform判断程序是否运行,且只能运行一个实例

    前言 判断程序是否已经运行,使程序只能运行一个实例有很多方法,下面记录两种. 目前使用的是第一种方法. 方法1:线程互斥 static class Program { private static S ...

  9. qt编写一个只能运行单个实例的程序,不用Windows API

    QtSingleApplicationhttp://code.qt.io/cgit/qt-solutions/qt-solutions.git/tree/qtsingleapplication 已打开 ...

随机推荐

  1. EF 批量更新删除(linq篇)

    刚开始用EF很多东西都不会用,事后想想都很简单的东西总是用很麻烦的方式实现 1:  EF的联合查询 inner join  很久很久以前我是这么写一个列表展示的,其中有两个字段Contractor和M ...

  2. Xamarin.Forms学习之Platform-specific API和文件操作

    这篇文章的分享原由是由于上篇关于Properties的保存不了,调用SavePropertiesAsync()方法也不行,所以我希望通过操作文件的方式保存我的需要的数据,然后我看了一下电子书中的第二十 ...

  3. echarts之series,markLine、markPoint

    一.标记线和标志点 markLine 标记线 标记线的添加,如最大值.最小值.平均值的标记线 symbol 标记的图形. data->type 特殊的标注类型,用于标注最大值最小值等. 可选: ...

  4. 20160924-1——mysql存储引擎

    一.主要存储引擎 5.5以后的版本,默认存储引擎从myisam改成了innodb:线上推荐都用innodb 二.innodb存储引擎 (一)结构 INNODB存储引擎大致分三部分,图中已经(1)(2) ...

  5. Python— 匿名函数

    匿名函数 匿名函数:为了解决那些功能很简单的需求而设计的  “一句话函数” #初始代码 def calc(n): return n**n print(calc(10)) #换成匿名函数 calc = ...

  6. 通过存储过程运行通过DBLINK的查询语句失败-单个语句成功--ORA-00604

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/q947817003/article/details/24419459 客户遇到个问题,描写叙述例如以 ...

  7. 使用Kotlin开发Android应用(IV):自定义视图和Android扩展

    在读完扩展函数和默认值这篇文章之后,那么接下来要介绍什么呢?在本系列第一篇文章中我们说过,Kotlin使得Android开发更加简单,本文我们将进一步作介绍. 自定义视图 你应该还记得,在说到Kotl ...

  8. Libsvm在matlab环境下使用指南

    一.安装 http://www.csie.ntu.edu.tw/~cjlin/libsvm/matlab/.在这个地址上可以下的包含matlab接口的源程序.下载完后可以放到放到任意的盘上解压,最好建 ...

  9. 剑指offer 面试56题

    面试56题: 题目:数组中数字出现的次数 题:一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 解题思路: 方法一:异或运算,详见<剑指offer&g ...

  10. Python基础(15)_python模块、包

    一.模块 1.什么是模块:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀 模块的本质:模块的本质是一个py文件 2.模块分为三类:1)内置模块:2)第三方模块: ...