Qt單一實例進程
想讓自己的程序只被啓動一次,如果已經運行,則不再重複開啓。看了網上很多資料,我這裏主要記錄其中兩種:
1. QSystemSemaphore、QSharedMemory
尊重原創:實現QT單例程序 QSystemSemaphore QSharedMemory
代碼稍作改動:
#include "mainwindow.h"
#include <QCoreApplication>
#include <QApplication>
#include <QSystemSemaphore>
#include <QSharedMemory>
#include <QMessageBox>
int main(int argc, char *argv[]) {
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
// 信號量的意義,把操作共享內存的代碼鎖住。因爲有可能同時點擊2次APP, 防止併發
QSystemSemaphore sema("SingleApp Key", 1, QSystemSemaphore::Open);
sema.acquire();
#ifdef Q_OS_LINUX
/* Windows平臺上不存在應用程序崩潰後,共享內存段還存在的情況
* LINUX應用程序崩潰後,共享內存段不會自動銷燬,則該程序再次運行會出問題
* 所以程序啓動時先去檢查是否有程序崩潰後還存留的共享內存段,如果有,先銷燬,再創建
*/
QSharedMemory mem("SingleApp");
// 嘗試將進程附加到共享內存段
if (mem.attach()) {
// 將共享內存與主進程分離, 如果此進程是附加到共享存儲器段的最後一個進程,則系統釋放共享存儲器段,即銷燬內容
mem.detach();
}
#endif
/*
* 每個App打開的時候,獲取一次共享內存。
* 如果獲取失敗,說明是第一個啓動的APP,直接創建共享內存就好了。
* 如果獲取成功,說明不是第一個,直接退出就好了。
* 保證App在系統裏只能打開一個。
*/
QSharedMemory unimem("SingleApp");
bool isRunning = false;
if (unimem.attach()) {
isRunning = true;
} else {
unimem.create(1);
isRunning = false;
}
sema.release();
if (isRunning) {
QMessageBox::warning(nullptr, "warning", "The app is running.");
exit(0);
}
MainWindow mainwindow;
mainwindow.show();
return app.exec();
}
2. QtSingleApplication
2.1.源碼下載
QSingleApplication是Qt提供的一個solution,它不包含在Qt的library中。遵循LGPL協議。
下載鏈接:qtsingleapplication
2.2.添加依賴
依賴於QtNetwork模塊(在使用的時候,記得添加QT + = network )
2.3.引入qtsingleapplication 源碼
include ($$PWD/qtsingleapplication/src/qtsinglecoreapplication.pri)
2.4.使用
可以參考:
Qt實現應用單實例運行(3)-使用QTSingleApplication
QTSingleApplication的用法
沒搞成功。。。所以就不寫了,解決了再補上。
老是報錯:
main.obj? error: LNK2019: 無法解析的外部符號 “public: __thiscall QtSingleApplication::QtSingleApplication(int &,char * *,bool)” (??0QtSingleApplication@@QAE@AAHPAPAD_N@Z),該符號在函數 _main 中被引用
main.obj? error: LNK2019: 無法解析的外部符號 “public: bool __thiscall QtSingleApplication::isRunning(void)” (?isRunning@QtSingleApplication@@QAE_NXZ),該符號在函數 _main 中被引用
值得mark的是,對於使用QGuiApplication的Qml應用是不能直接支持的。所以,需要修改qtsingleapplication的源代碼。 見:Qt單一實例進程——使用qtsingleapplication