一介绍

通过编写一个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中实现应用程序的单例化的更多相关文章

  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. Unity导航系统Navigation使用教程

    Unity开发VR之Vuforia 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- ...

  2. 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 ...

  3. c# 敏捷3 连接,批量处理,分页

    class Program { public class post { public int id { get; set; } public string name { get; set; } pub ...

  4. struts2的国际化i18n

    先来例子,普通的读取配置文件中不同语言信息,一个测试类,一份中文配置文件,一份英文配置文件 中文配置文件,书写中文“欢迎”,myelipse自动转码 public class Readi18n { p ...

  5. 依赖注入的方式测试ArrayList和LinkedList的效率(对依赖注入的再次理解)

    9/20 号再进行学习 在C++中,main函数尽可能的简单,只要调用子函数的一句话就实现了功能. java开发中,controller就相同于是main函数,其他类的方法不在本类中时候, 1.可以用 ...

  6. 把oracle数据库恢复到某个时间点或者某个scn

    alter session set nls_date_format='yyyymmdd hh24:mi:ss'; select sysdate from dual; conn dbauser/1234 ...

  7. linux之数据备份

    第一种方法:tar备份 [root@bogon ~]# cat bp/linux.txt no centos [root@bogon ~]# tar cvf bp.tar bp //打包bp目录 bp ...

  8. 你不知道的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. ...

  9. vscode vue eslint 快捷键格式化代码

    添加vetur , eslint插件   在工作区添加以下代码   "workbench.startupEditor": "welcomePage", &quo ...

  10. Why aren't more desktop apps written with Qt?

    Ref http://programmers.stackexchange.com/questions/88685/why-arent-more-desktop-apps-written-with-qt ...