Qt執行一個例項程序-3種方式簡介
阿新 • • 發佈:2019-01-24
semaphore.release();
三:使用QtSingleApplication
方案一:使用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();
}