QT中实现程序只运行一个实例--应用程序的单例化

简介:

起因


最近想实现一个应用程序单例化的程序,

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

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

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

3.利用QLocalServer
参照
Qt实现应用程序单实例运行–LocalServer方式
让QT只运行一个实例

4.QtSingleApplication
使用QT扩展库QtSingleApplication,能很好的解决这个问题.
QSingleApplication 是 Qt 提供的一个 solution ,它不包含在 Qt 的 library 中。遵循 LGPL 协议。关于如何使用,下载了这个 solution 之后,里面有例子。还有, QtCreator 中还用到了它。你也可以翻一番 QtCreator 的源代码。
里面就是用的QLocalServer/QLocalSocket建立本地socket来判断实例是否存在
在看到可以通过编写一个SingleApplication类来实现。

它提供了两个SingleApplication类,第一个用QSharedMemory, QLocalServer 和 QLocalSocket实现,第二个用QSharedMemory和QTimer实现,具体代码网页说明得很清楚,怎么使用也有代码示例。我自己也将代码做了测试,第二个类被我改成SingleApplication2。

编译之后,运行。找到编译出来的文件,再运行一次就可以看到效果了。两个SingleApplication类都用了Qt的共享内存,不同之处在于程序实例之间的通信(也就是程序第二个实例通知程序的第一个实例用户又一次运行了本程序,此时第一个实例可以做出相应的相应)用的方式不同。

如果两个程序实例之间直接不需要通信,那么直接使用共享内存实现就可以了,不需要QLocalServer 和 QLocalSocket或者QTimer。

使用qtsingleapplication实现qt程序单例


使用qtsingleapplication


使用QtSingleApplication 代替原来的QApplication类
该单例类中有一个isRunning()方法来判断当前程序是否在运行
因此使用方法如下

引入项目


将里面的qtsingleapplication目录拷贝到项目的源码目录中,

然后修改项目的.pro文件,引入加入qtsingleapplication工程,下面一行代码

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

QtSingleApplication 代替原来的QApplication类


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

#include <QtSingleApplication>
  • 1
  • 1

并且修改QtSingleApplication 代替原来的QApplication类

#include <QApplication>
#include <QtSingleApplication>
#include <QMessageBox>

int main(int argc, char *argv[])
{
    QtSingleApplication app(argc, argv);
    if (app.isRunning())
    {
        QMessageBox::information(NULL, "GLMPlayer",
                                 "Your GLMPLayer is already running ...",
                         QMessageBox::Ok);
        app.sendMessage("raise_window_noop");
        return EXIT_SUCCESS;
    }

    SingleApplication w;
    w.show();

    return app.exec();
}


默认情况下,QtSingleApplication使用QApplication::applicationFilePath作为自己的appId,用于识别不同的app

如果希望不受程序存放路径影响,则需要在指定appId即可。如下


 QtSingleApplication app(QLatin1String("my_app_id"),argc, argv);


这样即便是在不同的目录的程序,仍能互斥

发送消息和激活窗口


收发消息是QtSingleApplication特有的功能,而QApplication是不具有的。

默认情况下,QtSingleApplication接收到任何消息之后,都会自身的窗口窗口。如果不希望激活窗口,则可以自行设定,甚至重新连接信号槽。如下

app.setActivationWindow(&w,false); 

QObject::connect(&app, SIGNAL(messageReceived(const QString&)),&w, SLOT(handleMessage(const QString&))); 

目录
相关文章
|
4月前
|
Linux iOS开发 开发者
Qt问题(二):无法定位程序输入点于动态链接库
动态链接库(Dynamic Link Library,简称DLL)是一种可执行文件格式,常见于Windows操作系统中,而在Linux和macOS等其他操作系统中,相似的概念通常被称为共享库(Shared Library)。动态链接库允许程序在运行时加载所需的代码和数据,而不是在编译时静态链接到应用程序中。这种方式带来了几个重要的优点:
439 3
|
4月前
|
Linux 开发者 iOS开发
QT:基于QMediaPlayer制作的视频播放器(最下方有整合包,可直接运行)
QMediaPlayer是Qt多媒体模块中的一个核心类,它提供了播放音频和视频内容的功能。这个类的设计旨在简化跨平台的媒体播放,使得开发者能够在多种操作系统(如Linux、Windows、macOS及移动平台)上轻松集成多媒体播放能力到他们的应用中,而无需关心底层实现细节。以下是关于QMediaPlayer的一些关键点:
421 1
|
2月前
|
C语言 Android开发 C++
基于MTuner软件进行qt的mingw编译程序的内存泄漏检测
本文介绍了使用MTuner软件进行Qt MinGW编译程序的内存泄漏检测的方法,提供了MTuner的下载链接和测试代码示例,并通过将Debug程序拖入MTuner来定位内存泄漏问题。
基于MTuner软件进行qt的mingw编译程序的内存泄漏检测
|
2月前
|
设计模式 前端开发 安全
Qt注册类对象单例与单类型区别
在进行开发时,应当根据具体的应用场景和需求来选择使用单例模式或是单类型。如果是全局服务或状态管理,可能需要单例模式;如果是为了使QML环境下的不同组件能够访问到同一个后端服务对象,则可能需要使用单类型。
33 2
|
4月前
|
监控 Python
`pytest-qt` 是一个用于在 Qt 应用程序中进行 GUI 测试的 pytest 插件。
`pytest-qt` 是一个用于在 Qt 应用程序中进行 GUI 测试的 pytest 插件。
|
4月前
|
调度
【浅入浅出】Qt多线程机制解析:提升程序响应性与并发处理能力
在学习QT线程的时候我们首先要知道的是QT的主线程,也叫GUI线程,意如其名,也就是我们程序的最主要的一个线程,主要负责初始化界面并监听事件循环,并根据事件处理做出界面上的反馈。但是当我们只限于在一个主线程上书写逻辑时碰到了需要一直等待的事件该怎么办?它的加载必定会带着主界面的卡顿,这时候我们就要去使用多线程。
150 6
|
4月前
|
Linux 开发者 iOS开发
QT:基于QMediaPlayer制作的视频播放器(最下方有整合包,可直接运行)
QMediaPlayer是Qt多媒体模块中的一个核心类,它提供了播放音频和视频内容的功能。这个类的设计旨在简化跨平台的媒体播放,使得开发者能够在多种操作系统(如Linux、Windows、macOS及移动平台)上轻松集成多媒体播放能力到他们的应用中,而无需关心底层实现细节。以下是关于QMediaPlayer的一些关键点:
|
5月前
Qt MainWindow 程序主窗口
Qt MainWindow 程序主窗口
|
6月前
|
人工智能 编译器 C++
新版Qt6快速打包程序脚本
不知道啥时候Qt更新了,目前是6.7.0,项目默认的生成路径改了, 从 项目目录的同级目录 改为了 项目目录中的build目录, 之前的脚本也用不了了,所以用AI更新了一下脚本, 希望能帮到大家,方便快速打包程序到桌面。
156 9