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

网友投稿 539 2022-05-29

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

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();// 临界区

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

原文件代码

#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 << args.last(); else stream << QString(); stream.flush(); socket.waitForBytesWritten(); return; } newLocalServer(); } void SingleApplication::newLocalServer() { localServer = new QLocalServer(this); connect(localServer,SIGNAL(newConnection()),this,SLOT(newLocalConnectioin())); if(!localServer->listen(serverName)) { if(localServer->serverError() == QAbstractSocket::AddressInUseError) { QLocalServer::removeServer(serverName); localServer->listen(serverName); } } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

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; }

1

2

3

4

5

6

7

8

9

10

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

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

2.3使用官方的QSignalApplication

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

Qt

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:PDF文档签名证书帮助您签署可信的电子合同
下一篇:云化环境搭建
相关文章