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中是如何创建的.这里所谓的简单,就是指无属性注入,无复杂 ...
随机推荐
- Unity导航系统Navigation使用教程
Unity开发VR之Vuforia 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- ...
- Automatic Text Difficulty Classifier Assisting the Selection Of Adequate Reading Materials For European Portuguese Teaching --paper
the system uses existing Natural Language Processing (NLP) tools, a parser and an hyphenator, and tw ...
- c# 敏捷3 连接,批量处理,分页
class Program { public class post { public int id { get; set; } public string name { get; set; } pub ...
- struts2的国际化i18n
先来例子,普通的读取配置文件中不同语言信息,一个测试类,一份中文配置文件,一份英文配置文件 中文配置文件,书写中文“欢迎”,myelipse自动转码 public class Readi18n { p ...
- 依赖注入的方式测试ArrayList和LinkedList的效率(对依赖注入的再次理解)
9/20 号再进行学习 在C++中,main函数尽可能的简单,只要调用子函数的一句话就实现了功能. java开发中,controller就相同于是main函数,其他类的方法不在本类中时候, 1.可以用 ...
- 把oracle数据库恢复到某个时间点或者某个scn
alter session set nls_date_format='yyyymmdd hh24:mi:ss'; select sysdate from dual; conn dbauser/1234 ...
- linux之数据备份
第一种方法:tar备份 [root@bogon ~]# cat bp/linux.txt no centos [root@bogon ~]# tar cvf bp.tar bp //打包bp目录 bp ...
- 你不知道的JavaScript(下卷) (Kyle Simpson 著)
第一部分 起步上路 第1章 深入编程 1.1 代码 1.2 表达式 1.3 实践 1.3.1 输出 1.3.2 输入 1.4 运算符 1.5 值与类型 1.6 代码注释 1.7 变量 1.8 块 1. ...
- vscode vue eslint 快捷键格式化代码
添加vetur , eslint插件 在工作区添加以下代码 "workbench.startupEditor": "welcomePage", &quo ...
- Why aren't more desktop apps written with Qt?
Ref http://programmers.stackexchange.com/questions/88685/why-arent-more-desktop-apps-written-with-qt ...