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中是如何创建的.这里所谓的简单,就是指无属性注入,无复杂 ...
随机推荐
- xdoj-1298(模拟--简易SQL解释器)
题目链接 一 知识点: 1 substr有2种用法: 假设:string s = "0123456789"; string sub1 = s.substr( ...
- 【EOJ Monthly 2018.7】【D数蝌蚪】
https://acm.ecnu.edu.cn/contest/92/problem/D/ D. 数蝌蚪 Time limit per test: 2.0 seconds Memory limit: ...
- ng-repeat的用法:
-------------------------------------转载: 遍历数组: <li ng-repeat="item in array">{{it ...
- NDK: GCC 4.6 crashes
used version: NDK r9b, arm-linux-androideabi-4.6 GCC, with "-O2 -finline-limit=24". got t ...
- [原] Android上使用native IO
首先, 官方google play对APK大小有限制: 50M.( https://support.google.com/googleplay/android-developer/answer/113 ...
- mac-内置截图-snapshot
mac截图快捷键
- day7大纲
01 昨日内容回顾 数据类型补充: str <---> list split join list <---> set set(list) list(set()) list &l ...
- tensorflow object detection
Follow guidelin from https://github.com/tensorflow/models/blob/master/research/object_detection/g3do ...
- 3个问题:MySQL 中 character set 与 collation 的理解;utf8_general_ci 与 utf8_unicode_ci 区别;uft8mb4 默认collation:utf8mb4_0900_ai_ci 的含义
MySQL 中 character set 与 collation 的理解 出处:https://www.cnblogs.com/EasonJim/p/8128196.html 推荐: 编码使用 uf ...
- taro 组件的外部样式和全局样式
自定义组件对应的样式文件,只对该组件内的节点生效. 编写组件样式时,需要注意以下几点: 组件和引用组件的页面不能使用 id 选择器(#a).属性选择器([a])和标签名选择器,请改用 class 选择 ...