一介绍

通过编写一个QSingleApplication类,来实现Qt程序的单例化,原文的作者是在Windows Vista + Qt4.4 下实现的,不过应用在其他平台上是没问题的。(本文是我在http://www.qtcentre.org/wiki/index.php?title=SingleApplication上看到的)

二代码

方案一:使用Qt中的QSharedMemory,QLocalServer和QLocalSocket实现(不过需要在你的.pro里加上QT += network)

别的没翻译,就是大概说了一下,直接来代码吧:

  1. // "single_application.h"
  2.  
  3. #ifndef SINGLE_APPLICATION_H
  4. #define SINGLE_APPLICATION_H
  5.  
  6. #include <QApplication>
  7. #include <QSharedMemory>
  8. #include <QLocalServer>
  9.  
  10. class SingleApplication : public QApplication
  11.  
  12. {
  13. Q_OBJECT
  14. public:
  15.  
  16. SingleApplication(int &argc, char *argv[], const QString uniqueKey);
  17. bool isRunning();
  18. bool sendMessage(const QString &message);
  19. public slots:
  20. void receiveMessage();
  21. signals:
  22. void messageAvailable(QString message);
  23. private:
  24. bool _isRunning;
  25. QString _uniqueKey;
  26. QSharedMemory sharedMemory;
  27. QLocalServer *localServer;
  28. static const int timeout = 1000;
  29. };
  30.  
  31. #endif // SINGLE_APPLICATION_H
  1. // "single_application.cpp"
  2. #include <QLocalSocket>
  3. #include "single_application.h"
  4.  
  5. SingleApplication::SingleApplication(int &argc, char *argv[], const QString uniqueKey) : QApplication(argc, argv), _uniqueKey(uniqueKey)
  6.  
  7. {
  8. sharedMemory.setKey(_uniqueKey);
  9. if (sharedMemory.attach())
  10. _isRunning = true;
  11. else
  12. {
  13. _isRunning = false;
  14. // create shared memory.
  15. if (!sharedMemory.create(1))
  16. {
  17. qDebug("Unable to create single instance.");
  18. return;
  19. }
  20.  
  21. // create local server and listen to incomming messages from other instances.
  22. localServer = new QLocalServer(this);
  23. connect(localServer, SIGNAL(newConnection()), this, SLOT(receiveMessage()));
  24. localServer->listen(_uniqueKey);
  25. }
  26. }
  27.  
  28. // public slots.
  29. void SingleApplication::receiveMessage()
  30. {
  31. QLocalSocket *localSocket = localServer->nextPendingConnection();
  32. if (!localSocket->waitForReadyRead(timeout))
  33. {
  34. qDebug(localSocket->errorString().toLatin1());
  35. return;
  36. }
  37.  
  38. QByteArray byteArray = localSocket->readAll();
  39. QString message = QString::fromUtf8(byteArray.constData());
  40. emit messageAvailable(message);
  41. localSocket->disconnectFromServer();
  42. }
  43.  
  44. // public functions.
  45. bool SingleApplication::isRunning()
  46. {
  47. return _isRunning;
  48. }
  49.  
  50. bool SingleApplication::sendMessage(const QString &message)
  51. {
  52. if (!_isRunning)
  53. return false;
  54. QLocalSocket localSocket(this);
  55. localSocket.connectToServer(_uniqueKey, QIODevice::WriteOnly);
  56. if (!localSocket.waitForConnected(timeout))
  57. {
  58. qDebug(localSocket.errorString().toLatin1());
  59. return false;
  60. }
  61.  
  62. localSocket.write(message.toUtf8());
  63. if (!localSocket.waitForBytesWritten(timeout))
  64. {
  65. qDebug(localSocket.errorString().toLatin1());
  66. return false;
  67. }
  68.  
  69. localSocket.disconnectFromServer();
  70. return true;

方案二:使用Qt中的QSharedMemory,和QTimert实现,别的也没翻译,还是直接来代码吧:

  1. // "single_application.h"
  2. #ifndef SINGLE_APPLICATION_H
  3. #define SINGLE_APPLICATION_H
  4.  
  5. #include <QApplication>
  6. #include <QSharedMemory>
  7.  
  8. class SingleApplication : public QApplication
  9. {
  10. Q_OBJECT
  11. public:
  12. SingleApplication(int &argc, char *argv[], const QString uniqueKey);
  13. bool isRunning();
  14. bool sendMessage(const QString &message);
  15. public slots:
  16. void checkForMessage();
  17. signals:
  18. void messageAvailable(QString message);
  19. private:
  20. bool _isRunning;
  21. QSharedMemory sharedMemory;
  22. };
  23.  
  24. #endif // SINGLE_APPLICATION_H
  1. // "single_application.cpp"
  2. #include <QTimer>
  3. #include <QByteArray>
  4. #include "single_application.h"
  5.  
  6. SingleApplication::SingleApplication(int &argc, char *argv[], const QString uniqueKey) : QApplication(argc, argv)
  7. {
  8. sharedMemory.setKey(uniqueKey);
  9. if (sharedMemory.attach())
  10. _isRunning = true;
  11. else
  12. {
  13. _isRunning = false;
  14. // attach data to shared memory.
  15. QByteArray byteArray("0"); // default value to note that no message is available.
  16. if (!sharedMemory.create(byteArray.size()))
  17. {
  18. qDebug("Unable to create single instance.");
  19. return;
  20. }
  21. sharedMemory.lock();
  22. char *to = (char*)sharedMemory.data();
  23. const char *from = byteArray.data();
  24. memcpy(to, from, qMin(sharedMemory.size(), byteArray.size()));
  25. sharedMemory.unlock();
  26.  
  27. // start checking for messages of other instances.
  28. QTimer *timer = new QTimer(this);
  29. connect(timer, SIGNAL(timeout()), this, SLOT(checkForMessage()));
  30. timer->start(1000);
  31. }
  32. }
  33.  
  34. // public slots.
  35. void SingleApplication::checkForMessage()
  36. {
  37. sharedMemory.lock();
  38. QByteArray byteArray = QByteArray((char*)sharedMemory.constData(), sharedMemory.size());
  39. sharedMemory.unlock();
  40. if (byteArray.left(1) == "0")
  41. return;
  42. byteArray.remove(0, 1);
  43. QString message = QString::fromUtf8(byteArray.constData());
  44. emit messageAvailable(message);
  45.  
  46.   // remove message from shared memory.
  47. byteArray = "0";
  48. sharedMemory.lock();
  49. char *to = (char*)sharedMemory.data();
  50. const char *from = byteArray.data();
  51. memcpy(to, from, qMin(sharedMemory.size(), byteArray.size()));
  52. sharedMemory.unlock();
  53. }
  54.  
  55. // public functions.
  56. bool SingleApplication::isRunning()
  57. {
  58. return _isRunning;
  59. }
  60.  
  61. bool SingleApplication::sendMessage(const QString &message)
  62. {
  63. if (!_isRunning)
  64. return false;
  65.  
  66. QByteArray byteArray("1");
  67. byteArray.append(message.toUtf8());
  68. byteArray.append('/0'); // < should be as char here, not a string!
  69. sharedMemory.lock();
  70. char *to = (char*)sharedMemory.data();
  71. const char *from = byteArray.data();
  72. memcpy(to, from, qMin(sharedMemory.size(), byteArray.size()));
  73. sharedMemory.unlock();
  74. return true;
  75. }

三使用

  1. // "main.cpp"
  2. #include "single_application.h"
  3. int main(int argc, char *argv[])
  4. {
  5. SingleApplication app(argc, argv, "some unique key string");
  6. if (app.isRunning())
  7. {
  8. app.sendMessage("message from other instance.");
  9. return 0;
  10. }
  11.  
  12. MainWindow *mainWindow = new MainWindow();
  13.  
  14.   // connect message queue to the main window.
  15. QObject::connect(&app, SIGNAL(messageAvailable(QString)), mainWindow, SLOT(receiveMessage(QString)));
  16.  
  17.  // show mainwindow.
  18. mainWindow->show();
  19. return app.exec();
  20.  
  21. }
  22. 我想代码都应该能看得懂吧,这个挺不错的~

QT中实现应用程序的单例化的更多相关文章

  1. Unity3D中可中途释放的单例

    Unity3D中可中途释放的单例 使用静态类,静态变量的坏处是从程序加载后就一直占用内存,想要释放比较麻烦,可是之前使用的单例,没有提供释放的方法,那是不是也同静态的一样直到程序结束菜释放?那单例的好 ...

  2. QT中关闭应用程序和窗口的函数(quit(),exit()以及close()的区别)

    使用QT编辑界面,其中带来很大方便的一点就是Qt中自带丰富的.种类齐全的类及其功能函数,程序员可以在编辑程序的过程中简单地直接调用.关于窗口关闭的操作,在这里指出常用的三个槽,即quit(),exit ...

  3. Kotlin入门(28)Application单例化

    Application是Android的又一大组件,在App运行过程中,有且仅有一个Application对象贯穿应用的整个生命周期,所以适合在Application中保存应用运行时的全局变量.而开展 ...

  4. OSS - 有关于OSSClient的单例化

    之前在每个控制层OSSClient都是通过新new的方式创建OSSClientBuilder().build(endpoint,accessKeyId,accessKeySecret)进行创建 后期我 ...

  5. C#中的简单工厂和单例

    下面首先来说说简单工厂 举个例子: 首先是父类 public abstract class Pizza { public abstract string Info(); } } 子类 public c ...

  6. java中你确定用对单例了吗?

    作为程序员这样的特殊物种来说,都掌握了一种特殊能力就是编程思想,逻辑比較慎重,可是有时候总会忽略到一些细节,比方我,一直以来总认为Singleton是设计模式里最简单的,不用太在意,然而就是由于这样的 ...

  7. SpringMVC中的controller默认是单例的原因

    http://lavasoft.blog.51cto.com/62575/1394669/ 1.性能 :单例不用每次new浪费资源时间. 2.不需要:一般controller中不会定义属性这样单例就不 ...

  8. Java中反射和Unsafe破坏单例设计模式

    有如下单例模式设计代码: class Singleton { private String info = "HELLO SHIT"; private static Singleto ...

  9. Spring IoC 中的(Singleton)单例对象创建过程探索

    前言 之前将spring framework 源码导入了idea,后来折腾调试了一下,于是研究了一下最简单的singleton对象在spring中是如何创建的.这里所谓的简单,就是指无属性注入,无复杂 ...

随机推荐

  1. C#读取文件夹下所有指定类型,并返回相应类型数据

    C#读取文件夹下所有文件 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分享.心 ...

  2. 回文树&后缀自动机&后缀数组

    KMP,扩展KMP和Manacher就不写了,感觉没多大意思.   之前感觉后缀自动机简直可以解决一切,所以不怎么写后缀数组.   马拉车主要是通过对称中心解决问题,有的时候要通过回文串的边界解决问题 ...

  3. HDU5952 Counting Cliques (暴力深搜+剪枝) (2016ACM/ICPC亚洲赛区沈阳站 Problem E)

    题目链接:传送门 题目: Counting Cliques Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total S ...

  4. 如何运行简单的scrapy

    1.建scrapy工程 scrapy startproject python123demo 2.在工程中写一个爬虫文件 cd python123demo scrapy genspider demo p ...

  5. RESTful规范(二)

    七 解析器 解析器的作用: -用来解析前台传过来的数据编码方式 urlencoded:form表单:name=lqz&age= formdata :上传文件:--dadfgdgag-- jso ...

  6. 创建新用户,及用新用户名和密码登录--------------DCL

    创建用户基本语法:    creat user 用户名@"ip地址" identified by "密码" 登录数据库以后:用show databases; 显 ...

  7. 【HAOI2012】容易题

    终于自己做出一道题了quq 原题: 为了使得大家高兴,小Q特意出个自认为的简单题(easy)来满足大家,这道简单题是描述如下:有一个数列A已知对于所有的A[i]都是1~n的自然数,并且知道对于一些A[ ...

  8. 【BZOJ4553】【TJOI2016】【HEOI2016】序列

    cdq和整体二分之间的关系好迷啊 原题: 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值 可能会变化,但同一个时刻最多只有一个值发生变化.现在佳媛 ...

  9. What happens to our code? JavaScript 代码是怎样执行的

    1. 我们的代码第一步会被parser 语法分析程序分析. 如果没有报错之后 2. 生产SyntaxTree, 我们的代码会转换成machine code 3. 最终 我们的代码会被运行出来. 下面的 ...

  10. 一般化数值算法(accumluate,inner_product,partial_sum,adjacent_difference)

    accumulate template<class InputIterator, class T> T accumulate( InputIterator _First, InputIte ...