《qt5.12怎么没有QSingleApplication》
在 Qt 5.12 中,并没有直接提供一个名为QSingleApplication的类。QSingleApplication类实际上是 Qt 4 的一部分,用于实现一个应用程序的单实例运行。在 Qt 5 中,这一功能被重新实现,并被命名为QCoreApplication的一个特性所取代,即使用了QGuiApplication或QApplication类时,可以通过设置特定的参数来确保应用程序的单实例运行。
在 Qt 5 中,要实现单实例应用程序,你可以使用以下几种方法:
方法 1:使用QApplication的命令行参数
你可以通过检查命令行参数来确保应用程序只启动一次。例如,你可以使用QCommandLineParser或手动解析argv来检查是否已经有一个实例正在运行。
#include <QCoreApplication>
#include <QCommandLineParser>
#include <QLocalServer>
#include <QLocalSocket>
#include <QDebug>
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
QCoreApplication::setApplicationName("MySingleApp");
QCoreApplication::setOrganizationName("MyCompany");
QCoreApplication::setApplicationVersion("1.0");
// 检查是否已经有实例在运行
QLocalServer server(QStringLiteral("%1-%2").arg(QCoreApplication::applicationFilePath()).arg(quint64(QCoreApplication::applicationPid())));
if (!server.listen(QLocalSocket::LocalSocketName)) {
qDebug() << "An instance of this application is already running.";
return -1; // 或者可以尝试与已存在的实例通信
}
// 如果没有实例在运行,继续执行你的主函数逻辑
// ... 你的主函数逻辑 ...
return a.exec();
}
方法 2:编写QSingleApplication类
#ifndef SINGLE_APPLICATION_H
#define SINGLE_APPLICATION_H
#include <QApplication>
class QLocalServer;
class QSingleApplication : public QApplication
{
Q_OBJECT
public:
QSingleApplication(int argc, char **argv);
// 判断进程是否存在
bool isRunning();
private slots:
void newLocalConnection();
private:
QLocalServer *pServer;
bool bRunning;
};
#endif // SINGLE_APPLICATION_H
#include "qsingleapplication.h"
#include <QLocalSocket>
#include <QLocalServer>
#include <QFile>
#include <QTextStream>
QSingleApplication::QSingleApplication(int argc, char **argv)
: QApplication(argc, argv),
bRunning(false)
{
QCoreApplication::setApplicationName("BPaaa");
QCoreApplication::setApplicationVersion("VERSION_STRING");
QCoreApplication::setOrganizationName("BPabc");
QCoreApplication::setOrganizationDomain("https://github.com");
QString strServerName = QCoreApplication::organizationName() + QCoreApplication::applicationName();
QLocalSocket socket;
socket.connectToServer(strServerName);
if (socket.waitForConnected(500))
{
QTextStream stream(&socket);
QStringList args = QCoreApplication::arguments();
QString strArg = (args.count() > 1) ? args.last() : "";
stream << strArg;
stream.flush();
qDebug() << "Have already connected to server.";
socket.waitForBytesWritten();
bRunning = true;
}
else
{
// 如果不能连接到服务器,则创建一个
pServer = new QLocalServer(this);
connect(pServer, SIGNAL(newConnection()), this, SLOT(newLocalConnection()));
if (pServer->listen(strServerName))
{
// 防止程序崩溃,残留进程服务,直接移除
if ((pServer->serverError() == QAbstractSocket::AddressInUseError) && QFile::exists(pServer->serverName()))
{
QFile::remove(pServer->serverName());
pServer->listen(strServerName);
}
}
}
}
void QSingleApplication::newLocalConnection()
{
QLocalSocket *pSocket = pServer->nextPendingConnection();
if (pSocket != nullptr)
{
pSocket->waitForReadyRead(1000);
QTextStream in(pSocket);
QString strValue;
in >> strValue;
qDebug() << QString("The value is: %1").arg(strValue);
delete pSocket;
pSocket = nullptr;
}
}
bool QSingleApplication::isRunning()
{
return bRunning;
}
int main(int argc, char *argv[])
{
// QApplication a(argc, argv); //替换掉这一句
QSingleApplication a(argc, argv);
if(a.isRunning())
{
return 0;
}
......
......
return a.exec();
}
三 通过共享内存方式实现
QSystemSemaphore sema("AA",1, QSystemSemaphore::Open);
sema.acquire();// 在临界区操作共享内存 SharedMemory
QSharedMemory mem("AAAAA");// 全局对象名
if (!mem.create(1))// 如果全局对象已存在则退出
{
sema.release(); // 如果是 Unix 系统,会自动释放。
return 0;
}