在开发项目的工程中,我们经常希望只运行一个相同的Qt实例进程。当然也可以像类似QQ那样,同时登录多个不同的账号!为了避免这个问题,介绍以下几种用法,每一个解决方案都适用于特定的情况,所以必须尝试和适用合适的解决方案。
方式:首先一个新的实例启动时,将尝试连接到同一个本地服务器,如果连接失败,则表示第一个实例进程,创建一个本地服务器。否则,进行退出。
void MainWidget::initLocalConnection() { is_running = false; QCoreApplication::setApplicationName("localserver"); QString serverName = QCoreApplication::applicationName(); QLocalSocket socket; socket.connectToServer(serverName); if(socket.waitForConnected(500)) { is_running = true; return; } //连接不上服务器,就创建一个 server = new QLocalServer(this); connect(server, SIGNAL(newConnection()), this, SLOT(newLocalConnection())); if(server->listen(serverName)) { //防止程序崩溃时,残留进程服务,移除之 if(server->serverError() == QAbstractSocket::AddressInUseError && QFile::exists(server->serverName())) { QFile::remove(server->serverName()); server->listen(serverName); } } } void MainWidget::newLocalConnection() { QLocalSocket *socket = server->nextPendingConnection(); if(!socket) return; socket->waitForReadyRead(1000); delete socket; } bool MainWidget::isRunning() { return is_running; }
MainWidget main_widget; if(!main_widget.isRunning()) { main_widget.showNormal(); main_widget.raise(); main_widget.activateWindow(); return app.exec(); }
二:使用QSharedMemory
方式:先创建一个共享内存,然后在每一个应用程序开始运行之前进行检查是否可以创建一个具有相同unique_id的共享内存,如果不能,则表示创建了实例正在运行。
QSharedMemory shared_memory; shared_memory.setKey(unique_id); if(shared_memory.attach()) { return 0; } if(shared_memory.create(1)) { MainWidget main_widget; main_widget.showNormal(); main_widget.raise(); main_widget.activateWindow(); return app.exec(); }
另一种方法:http://blog.csdn.net/yangxiao_0203/article/details/9622781
附:方法二main.cpp中的完整代码示例
//mian.cpp #include "mainwindow.h" #include <QApplication> #include <QSharedMemory> #include <QMessageBox> int main(int argc, char *argv[]) { QApplication a(argc, argv); QSharedMemory shared_memory; shared_memory.setKey("THISISATEST00594869"); if(shared_memory.attach()) { QMessageBox::information(0,"Information","This program is running already.",QMessageBox::Yes); return 0; } if(shared_memory.create(1)) { MainWindow w; w.show(); return a.exec(); } return -1; }