QtSingleApplication 默认使用Widget,对于Widget的应用,可以直接支持,对于使用QGuiApplication的Qml应用是不能直接支持的。所以,可能需要修改qtsingleapplication的源代码。
1、使用QtSingleApplication 实现qt程序单例
使用QtSingleApplication 代替原来的QApplication类,该单例类中有一个isRunning()方法来判断当前程序是否在运行
因此使用方法如下:
将里面的qtsingleapplication目录拷贝到项目的源码目录中,
然后修改项目的.pro文件,引入加入qtsingleapplication工程,下面一行代码
include(../qtsingleapplication/src/qtsingleapplication.pri)
QtSingleApplication 代替原来的QApplication类
#include <QApplication>
#include <QtSingleApplication>
#include <QMessageBox>
int main(int argc, char *argv[])
{
QtSingleApplication app(argc, argv);
if (app.isRunning())
{
QMessageBox::information(NULL, "MyAPP", "MyAPP is already running ...",
QMessageBox::Ok);
app.sendMessage("sdsds");
return EXIT_SUCCESS;
}
SingleApplication w;
w.show();
return app.exec();
}
默认情况下,QtSingleApplication使用QApplication::applicationFilePath作为自己的appID,用于识别不同的app。
如果希望不受程序存放路径影响,则需要在指定appID即可。如下
QtSingleApplication app(QLatin1String("my_app_id_44"),argc, argv);
这样即便是在不同的目录的程序,仍能互斥。
注意事项:
单例执行一般有两种需求:
1)、默认情况下,QtSingleApplication使用QApplication::applicationFilePath作为自己的appID,用于识别不同的app。此时如果再本机上有一个exe的实例在运行,另外别的路径下该exe实例也可以运行。
2)、如果本机上只允许有一个实例运行,那么就用一个固定的字符串作为标记,无论本机上有多少个该应用程序副本,同时最多也只能有一个实例在运行 。
需要说明的是,实现单例运行的逻辑是根据APP_ID,在临时目录下存在一个对应于APP_ID的文件。如果开启了一个实例,然后删除对应的文件,然后就可以再次开启一个实例。
特别需要说明的是,如果是在linux开发,涉及到局域网内远程计算机的执行该程序,无论是使用固定字符串还是文件路径作为APP_ID做为标记都会导致本机、远程计算机同时只能运行一个实例。但有时需求并不是这样,而是一个终端可以有一个实例运行,那么这时, 把APP_ID的参数加上远程访问的计算机IP信息加上。
发消息
收发消息是QtSingleApplication特有的功能,而QApplication是不具有的。
默认情况下,QtSingleApplication接收到任何消息之后,都会激活自己的窗口。如果不希望激活窗口,则可以自行设定,甚至重新连接信号槽。
实际应用中往往需要执行的是如果有实例在运行,要么给出提示信息,要么直接把正在运行的实例的窗口显示出来。
QtSingleApplication提供了一个public slots: bool sendMessage(const QString& message, int timeout = 5000);和一个信号void messageReceived(const QString& message);
void FrmMain::sltMessageReceived(const QString &msg)
{
Qt::WindowFlags flags = windowFlags();
flags |= Qt::WindowStaysOnTopHint;
setWindowFlags(flags);
show();
flags &= ~Qt::WindowStaysOnTopHint;
setWindowFlags(flags);
showNormal();
if(msg != qApp->applicationFilePath()) {
const QString& warnStr(tr("Only on instance is allowed. Close running application first."));
QMessageBox::warning(this, tr("Warn"), warnStr, QMessageBox::Ok);
}
}
参考:https://blog.csdn.net/iamsujin/article/details/53257038