QT中实现应用程序的单例化
一介绍
通过编写一个QSingleApplication类,来实现Qt程序的单例化,原文的作者是在Windows Vista + Qt4.4 下实现的,不过应用在其他平台上是没问题的。(本文是我在http://www.qtcentre.org/wiki/index.php?title=SingleApplication上看到的)
二代码
方案一:使用Qt中的QSharedMemory,QLocalServer和QLocalSocket实现(不过需要在你的.pro里加上QT += network)
别的没翻译,就是大概说了一下,直接来代码吧:
- // "single_application.h"
- #ifndef SINGLE_APPLICATION_H
- #define SINGLE_APPLICATION_H
- #include <QApplication>
- #include <QSharedMemory>
- #include <QLocalServer>
- class SingleApplication : public QApplication
- {
- Q_OBJECT
- public:
- SingleApplication(int &argc, char *argv[], const QString uniqueKey);
- bool isRunning();
- bool sendMessage(const QString &message);
- public slots:
- void receiveMessage();
- signals:
- void messageAvailable(QString message);
- private:
- bool _isRunning;
- QString _uniqueKey;
- QSharedMemory sharedMemory;
- QLocalServer *localServer;
- static const int timeout = 1000;
- };
- #endif // SINGLE_APPLICATION_H
- // "single_application.cpp"
- #include <QLocalSocket>
- #include "single_application.h"
- SingleApplication::SingleApplication(int &argc, char *argv[], const QString uniqueKey) : QApplication(argc, argv), _uniqueKey(uniqueKey)
- {
- sharedMemory.setKey(_uniqueKey);
- if (sharedMemory.attach())
- _isRunning = true;
- else
- {
- _isRunning = false;
- // create shared memory.
- if (!sharedMemory.create(1))
- {
- qDebug("Unable to create single instance.");
- return;
- }
- // create local server and listen to incomming messages from other instances.
- localServer = new QLocalServer(this);
- connect(localServer, SIGNAL(newConnection()), this, SLOT(receiveMessage()));
- localServer->listen(_uniqueKey);
- }
- }
- // public slots.
- void SingleApplication::receiveMessage()
- {
- QLocalSocket *localSocket = localServer->nextPendingConnection();
- if (!localSocket->waitForReadyRead(timeout))
- {
- qDebug(localSocket->errorString().toLatin1());
- return;
- }
- QByteArray byteArray = localSocket->readAll();
- QString message = QString::fromUtf8(byteArray.constData());
- emit messageAvailable(message);
- localSocket->disconnectFromServer();
- }
- // public functions.
- bool SingleApplication::isRunning()
- {
- return _isRunning;
- }
- bool SingleApplication::sendMessage(const QString &message)
- {
- if (!_isRunning)
- return false;
- QLocalSocket localSocket(this);
- localSocket.connectToServer(_uniqueKey, QIODevice::WriteOnly);
- if (!localSocket.waitForConnected(timeout))
- {
- qDebug(localSocket.errorString().toLatin1());
- return false;
- }
- localSocket.write(message.toUtf8());
- if (!localSocket.waitForBytesWritten(timeout))
- {
- qDebug(localSocket.errorString().toLatin1());
- return false;
- }
- localSocket.disconnectFromServer();
- return true;
方案二:使用Qt中的QSharedMemory,和QTimert实现,别的也没翻译,还是直接来代码吧:
- // "single_application.h"
- #ifndef SINGLE_APPLICATION_H
- #define SINGLE_APPLICATION_H
- #include <QApplication>
- #include <QSharedMemory>
- class SingleApplication : public QApplication
- {
- Q_OBJECT
- public:
- SingleApplication(int &argc, char *argv[], const QString uniqueKey);
- bool isRunning();
- bool sendMessage(const QString &message);
- public slots:
- void checkForMessage();
- signals:
- void messageAvailable(QString message);
- private:
- bool _isRunning;
- QSharedMemory sharedMemory;
- };
- #endif // SINGLE_APPLICATION_H
- // "single_application.cpp"
- #include <QTimer>
- #include <QByteArray>
- #include "single_application.h"
- SingleApplication::SingleApplication(int &argc, char *argv[], const QString uniqueKey) : QApplication(argc, argv)
- {
- sharedMemory.setKey(uniqueKey);
- if (sharedMemory.attach())
- _isRunning = true;
- else
- {
- _isRunning = false;
- // attach data to shared memory.
- QByteArray byteArray("0"); // default value to note that no message is available.
- if (!sharedMemory.create(byteArray.size()))
- {
- qDebug("Unable to create single instance.");
- return;
- }
- sharedMemory.lock();
- char *to = (char*)sharedMemory.data();
- const char *from = byteArray.data();
- memcpy(to, from, qMin(sharedMemory.size(), byteArray.size()));
- sharedMemory.unlock();
- // start checking for messages of other instances.
- QTimer *timer = new QTimer(this);
- connect(timer, SIGNAL(timeout()), this, SLOT(checkForMessage()));
- timer->start(1000);
- }
- }
- // public slots.
- void SingleApplication::checkForMessage()
- {
- sharedMemory.lock();
- QByteArray byteArray = QByteArray((char*)sharedMemory.constData(), sharedMemory.size());
- sharedMemory.unlock();
- if (byteArray.left(1) == "0")
- return;
- byteArray.remove(0, 1);
- QString message = QString::fromUtf8(byteArray.constData());
- emit messageAvailable(message);
- // remove message from shared memory.
- byteArray = "0";
- sharedMemory.lock();
- char *to = (char*)sharedMemory.data();
- const char *from = byteArray.data();
- memcpy(to, from, qMin(sharedMemory.size(), byteArray.size()));
- sharedMemory.unlock();
- }
- // public functions.
- bool SingleApplication::isRunning()
- {
- return _isRunning;
- }
- bool SingleApplication::sendMessage(const QString &message)
- {
- if (!_isRunning)
- return false;
- QByteArray byteArray("1");
- byteArray.append(message.toUtf8());
- byteArray.append('/0'); // < should be as char here, not a string!
- sharedMemory.lock();
- char *to = (char*)sharedMemory.data();
- const char *from = byteArray.data();
- memcpy(to, from, qMin(sharedMemory.size(), byteArray.size()));
- sharedMemory.unlock();
- return true;
- }
三使用
- // "main.cpp"
- #include "single_application.h"
- int main(int argc, char *argv[])
- {
- SingleApplication app(argc, argv, "some unique key string");
- if (app.isRunning())
- {
- app.sendMessage("message from other instance.");
- return 0;
- }
- MainWindow *mainWindow = new MainWindow();
- // connect message queue to the main window.
- QObject::connect(&app, SIGNAL(messageAvailable(QString)), mainWindow, SLOT(receiveMessage(QString)));
- // show mainwindow.
- mainWindow->show();
- return app.exec();
- }
- 我想代码都应该能看得懂吧,这个挺不错的~
QT中实现应用程序的单例化的更多相关文章
- Unity3D中可中途释放的单例
Unity3D中可中途释放的单例 使用静态类,静态变量的坏处是从程序加载后就一直占用内存,想要释放比较麻烦,可是之前使用的单例,没有提供释放的方法,那是不是也同静态的一样直到程序结束菜释放?那单例的好 ...
- QT中关闭应用程序和窗口的函数(quit(),exit()以及close()的区别)
使用QT编辑界面,其中带来很大方便的一点就是Qt中自带丰富的.种类齐全的类及其功能函数,程序员可以在编辑程序的过程中简单地直接调用.关于窗口关闭的操作,在这里指出常用的三个槽,即quit(),exit ...
- Kotlin入门(28)Application单例化
Application是Android的又一大组件,在App运行过程中,有且仅有一个Application对象贯穿应用的整个生命周期,所以适合在Application中保存应用运行时的全局变量.而开展 ...
- OSS - 有关于OSSClient的单例化
之前在每个控制层OSSClient都是通过新new的方式创建OSSClientBuilder().build(endpoint,accessKeyId,accessKeySecret)进行创建 后期我 ...
- C#中的简单工厂和单例
下面首先来说说简单工厂 举个例子: 首先是父类 public abstract class Pizza { public abstract string Info(); } } 子类 public c ...
- java中你确定用对单例了吗?
作为程序员这样的特殊物种来说,都掌握了一种特殊能力就是编程思想,逻辑比較慎重,可是有时候总会忽略到一些细节,比方我,一直以来总认为Singleton是设计模式里最简单的,不用太在意,然而就是由于这样的 ...
- SpringMVC中的controller默认是单例的原因
http://lavasoft.blog.51cto.com/62575/1394669/ 1.性能 :单例不用每次new浪费资源时间. 2.不需要:一般controller中不会定义属性这样单例就不 ...
- Java中反射和Unsafe破坏单例设计模式
有如下单例模式设计代码: class Singleton { private String info = "HELLO SHIT"; private static Singleto ...
- Spring IoC 中的(Singleton)单例对象创建过程探索
前言 之前将spring framework 源码导入了idea,后来折腾调试了一下,于是研究了一下最简单的singleton对象在spring中是如何创建的.这里所谓的简单,就是指无属性注入,无复杂 ...
随机推荐
- C#读取文件夹下所有指定类型,并返回相应类型数据
C#读取文件夹下所有文件 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分享.心 ...
- 回文树&后缀自动机&后缀数组
KMP,扩展KMP和Manacher就不写了,感觉没多大意思. 之前感觉后缀自动机简直可以解决一切,所以不怎么写后缀数组. 马拉车主要是通过对称中心解决问题,有的时候要通过回文串的边界解决问题 ...
- HDU5952 Counting Cliques (暴力深搜+剪枝) (2016ACM/ICPC亚洲赛区沈阳站 Problem E)
题目链接:传送门 题目: Counting Cliques Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total S ...
- 如何运行简单的scrapy
1.建scrapy工程 scrapy startproject python123demo 2.在工程中写一个爬虫文件 cd python123demo scrapy genspider demo p ...
- RESTful规范(二)
七 解析器 解析器的作用: -用来解析前台传过来的数据编码方式 urlencoded:form表单:name=lqz&age= formdata :上传文件:--dadfgdgag-- jso ...
- 创建新用户,及用新用户名和密码登录--------------DCL
创建用户基本语法: creat user 用户名@"ip地址" identified by "密码" 登录数据库以后:用show databases; 显 ...
- 【HAOI2012】容易题
终于自己做出一道题了quq 原题: 为了使得大家高兴,小Q特意出个自认为的简单题(easy)来满足大家,这道简单题是描述如下:有一个数列A已知对于所有的A[i]都是1~n的自然数,并且知道对于一些A[ ...
- 【BZOJ4553】【TJOI2016】【HEOI2016】序列
cdq和整体二分之间的关系好迷啊 原题: 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值 可能会变化,但同一个时刻最多只有一个值发生变化.现在佳媛 ...
- What happens to our code? JavaScript 代码是怎样执行的
1. 我们的代码第一步会被parser 语法分析程序分析. 如果没有报错之后 2. 生产SyntaxTree, 我们的代码会转换成machine code 3. 最终 我们的代码会被运行出来. 下面的 ...
- 一般化数值算法(accumluate,inner_product,partial_sum,adjacent_difference)
accumulate template<class InputIterator, class T> T accumulate( InputIterator _First, InputIte ...