一种单开的方法是使用Qt中的QLocalServer类(在win下是管道,linux下是文件)
直接看代码
.h
class SingleInstance : public QObject
{
Q_OBJECT
public:
SingleInstance(const QString& id, QObject* parent = 0);
~SingleInstance();
QString getLastErrorString() const;
bool start();
bool hasPreviousInstance();
Q_SIGNALS:
void newInstanceCreated();
private Q_SLOTS:
void onNewConnection();
private:
QLocalServer mServer;
QString mName;
};
.cpp
#include "singleinstance.h"
SingleInstance::SingleInstance(const QString& name, QObject* parent)
: QObject(parent), mName(name)
{
connect(&mServer, &QLocalServer::newConnection, this, &SingleInstance::onNewConnection);
}
SingleInstance::~SingleInstance()
{
}
QString SingleInstance::getLastErrorString() const
{
return mServer.errorString();
}
bool SingleInstance::start()
{
mServer.removeServer(mName);
return mServer.listen(mName);
}
bool SingleInstance::hasPreviousInstance()
{
QLocalSocket socket;
socket.connectToServer(mName);
return socket.waitForConnected();
}
void SingleInstance::onNewConnection()
{
emit newInstanceCreated();
}
在main.cpp中使用
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
app.setQuitOnLastWindowClosed(false);
SingleInstance si("prog-name");
if (si.hasPreviousInstance()) {
return EXIT_SUCCESS;
}
if (!si.start()) {
qDebug() << si.getLastErrorString();
return EXIT_FAILURE;
}
MainWindow mainWindow;
mainWindow.show();
QObject::connect(&si, &SingleInstance::newInstanceCreated, [&mainWindow]() {
mainWindow.setMainWindowVisibility(true);
});
return app.exec();
在hasPriviousInstance函数中:用QLocalServer去连接同名的server,返回连接结果;
1.连接失败:说明不存在,继续调用start()函数,mServer.removeServer(mName),return mServer.listen(mName);返回监听结果,正常执行程序。
2.连接成功:说明已经存在,直接退出本程序;第一个进程会收到连接请求,onNewConnection函数中产生newInstanceCreated信号,mainWindow.setMainWindowVisibility(true)被调用,从而第一个进程界面显示出来。