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&))); 

目录
相关文章
|
9天前
|
Web App开发 存储 Linux
Linux(33)Rockchip RK3568 Ubuntu22.04上通过SSH运行Qt程序和关闭Chrome的密钥提示
Linux(33)Rockchip RK3568 Ubuntu22.04上通过SSH运行Qt程序和关闭Chrome的密钥提示
43 0
|
1月前
|
C语言 Windows
Qt 应用程序打包成安装文件
Qt 应用程序打包成安装文件
10 0
|
1月前
【QT】读写.ini配置文件的程序实现
【QT】读写.ini配置文件的程序实现
|
2月前
|
安全 网络协议 数据安全/隐私保护
掌握Qt和C++:构建你的第一个P2P应用程序
掌握Qt和C++:构建你的第一个P2P应用程序
120 3
|
7天前
|
开发框架 自然语言处理 Linux
Qt:构建强大跨平台应用程序的框架
Qt:构建强大跨平台应用程序的框架
|
1天前
|
人工智能 编译器 C++
新版Qt6快速打包程序脚本
不知道啥时候Qt更新了,目前是6.7.0,项目默认的生成路径改了, 从 项目目录的同级目录 改为了 项目目录中的build目录, 之前的脚本也用不了了,所以用AI更新了一下脚本, 希望能帮到大家,方便快速打包程序到桌面。
15 9
|
3天前
|
开发框架 编译器 C++
Qt:一个强大的跨平台C++应用程序开发框架
Qt:一个强大的跨平台C++应用程序开发框架
11 1
|
3天前
|
开发框架 Linux C++
Qt:强大的跨平台C++应用程序开发框架
Qt:强大的跨平台C++应用程序开发框架
15 3
|
9天前
|
开发框架 编译器 开发者
QT环境搭建详解及实例展示
QT环境搭建详解及实例展示
26 0
|
16天前
|
数据可视化
实现Hello Qt 程序
实现Hello Qt 程序