Qt6 防止程序多重启动,并实现双击图标显示已运行的程序

您所在的位置:网站首页 funcom启动程序 Qt6 防止程序多重启动,并实现双击图标显示已运行的程序

Qt6 防止程序多重启动,并实现双击图标显示已运行的程序

2024-06-23 10:02| 来源: 网络整理| 查看: 265

titlle bar

欢迎来到我的博客,希望这篇文章对你有所帮助,如果觉得不错,请点赞搜藏哈。

1 需求背景

还是原来的网络关机助手项目“PowerControl”,目前他有了一个新的运行环境,就是在我们的某个带有电脑的显示设备上面,可以理解为带有触摸功能的一体机,本来原生设计是无法触发这个需求的,但是由于信号的干扰没有很好的解决,导致整个屏幕下沉,屏幕的四周没法触摸,这就导致了Windows无法关机,也无法打开系统托盘。所以,关机就需要使用我的关机助手的界面来关机。

但是我的程序图标点击默认是启动程序,而我的程序有没有限制,而且默认还是最小化的,点再多也没有用,指示多开 了一堆程序而已。

所以本次需要增加以下功能

程序启动只能有一个进程,不能多开

双击桌面图标,如果程序启动,则显示程序,如果没有,则创建程序。

2 解决方案

要实现上面的功能,我先想到的就是寻找进程,程序启动的时候看看有没有这个的东西,但是呢,有没有搞过,这都21世纪了,百度一下,发现一个有很多种方法大致有一下几种

参考链接,这里只做搬运 https://blog.csdn.net/robertkun/article/details/8518576#

2.1共享内存

据说这种方法在Linux系统下会有一个内存释放的问题,在某种情况下会引起程序的异常或崩溃

核心代码如下

// 确保只运行一次 QSystemSemaphore sema("JAMKey",1,QSystemSemaphore::Open); sema.acquire();// 在临界区操作共享内存 SharedMemory QSharedMemory mem("SystemObject");// 全局对象名 if (!mem.create(1))// 如果全局对象以存在则退出 { QMessageBox::information(0, MESSAGEBOXTXT,"An instance has already been running."); sema.release();// 如果是 Unix 系统,会自动释放。 return 0; } sema.release();// 临界区 2.2使用QLocalServer和QLocalSocker

这种也是我使用的版本,参考链接找不到,不过代码都是找搬过来的,连接:https://blog.csdn.net/sunflover454/article/details/50426639

头文件代码

#ifndef SINGLEAPPLICATION_H #define SINGLEAPPLICATION_H #include #include class QWidget; class QLocalServer; class SingleApplication : public QApplication { Q_OBJECT public: SingleApplication(int &argc,char **argv); bool isRuning(); QWidget *mainWindow; private slots: void newLocalConnectioin(); private: void initLocalConnection(); void newLocalServer(); bool bRunning; QLocalServer *localServer; QString serverName; }; #endif // SINGLEAPPLICATION_H

原文件代码

#include "singleapplication.h" #include #include #include #include #include SingleApplication::SingleApplication(int &argc, char **argv) :QApplication(argc,argv),bRunning(false),localServer(nullptr),mainWindow(nullptr) { serverName = QFileInfo(QCoreApplication::applicationFilePath()).fileName(); initLocalConnection(); } bool SingleApplication::isRuning() { return bRunning; } void SingleApplication::newLocalConnectioin() { QLocalSocket *socket = localServer->nextPendingConnection(); if(!socket) return; socket->waitForReadyRead(1000); QTextStream stream(socket); delete socket; if(mainWindow != NULL) { mainWindow->raise(); mainWindow->activateWindow(); mainWindow->setWindowState((mainWindow->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); mainWindow->show(); } } void SingleApplication::initLocalConnection() { bRunning = false; QLocalSocket socket; socket.connectToServer(serverName); if(socket.waitForConnected(500)) { bRunning = true; QTextStream stream(&socket); QStringList args = QCoreApplication::arguments(); if(args.count() > 1) stream serverError() == QAbstractSocket::AddressInUseError) { QLocalServer::removeServer(serverName); localServer->listen(serverName); } } }

main 调用

#include "mainwindow.h" #include #include void autoStart() { QString appName = QApplication::applicationName(); QString appPath = QApplication::applicationFilePath(); appPath = appPath.replace("/","\\"); QSettings *reg=new QSettings("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",QSettings::NativeFormat); QString val = reg->value(appName).toString(); if(val != appPath) reg->setValue(appName,appPath); reg->deleteLater(); } //int main(int argc, char *argv[]) //{ // QApplication a(argc, argv); // autoStart(); // MainWindow w; w.show(); // return a.exec(); //} int main(int argc, char *argv[]) { SingleApplication a(argc, argv); if(!a.isRuning()) { autoStart(); MainWindow w; a.mainWindow = &w; // w.show(); return a.exec(); } return 0; } 2.3使用官方的QSignalApplication

官方类,但是默认不在Qt中,需要自己下载安装:参考链接https://blog.csdn.net/bloke_come/article/details/106319236

博客签名2021



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3