概述
库QtSingleApplication
源自Qt-Solutions
,长期维护。
用于创建单实例应用程序。
代码解析
构造函数
1 2 3 4 5 6 7 8 9 10 11 12
| public: QtSingleApplication(int &argc, char **argv, bool GUIenabled = true); QtSingleApplication(const QString &id, int &argc, char **argv);
#if QT_VERSION < 0x050000 QtSingleApplication(int &argc, char **argv, Type type);
# if defined(Q_WS_X11) QtSingleApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0); QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap= 0); QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0); # endif
|
各类构造函数都是对QApplication
的重写,调用了sysInit
函数。
sysInit函数
上文说到,QtSingleApplication
的构造函数都是对QApplication
的重写。
1 2 3 4 5 6
| void QtSingleApplication::sysInit(const QString &appId) { actWin = 0; peer = new QtLocalPeer(this, appId); connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); }
|
QtLocalPeer
其中关键对象为QtLocalPeer
,其提供的主要函数如下
1 2 3 4 5 6 7 8 9
| public: QtLocalPeer(QObject *parent = 0, const QString &appId = QString()); bool isClient(); bool sendMessage(const QString &message, int timeout); QString applicationId() const;
|
QtSingleApplication其他关键函数
是否有实例运行中
1 2 3 4
| bool QtSingleApplication::isRunning() { return peer->isClient(); }
|
通过内部QtLocalPeer
对象的isClient
函数判断是否运行有实例。
消息的传递
1 2 3 4 5
| public Q_SLOTS: bool QtSingleApplication::sendMessage(const QString &message, int timeout = 5000) { return peer->sendMessage(message, timeout); }
|
通过内部QtLocalPeer
对象的sendMessage
函数,向服务器发送消息:当有多个实例时,如果当前实例为服务器,则直接返回,如果为客户端,则通过QLocalSocket
连接到当前应用程序唯一ID的QLocalServer
,以传递消息。
案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #include <qtsingleapplication.h>
int main(int argc, char *argv[]) { QtSingleApplication app(QString("appId"),argc,argv); if (app.isRunning()) { app.sendMessage("raise_window_noop"); return EXIT_SUCCESS; } MainWindow m; app.setActivationWindow(&m); m.show(); return app.exec(); }
|
当调用了setActivationWindow
后,单例应用程序收到消息时,会调用activateWindow
函数,激活窗口。
当然如果不希望激活窗口,可以使用setActivationWindow(&windowName,false)
取消设置,并自行书写槽函数MainWindow::messageHandle(const QString& msg)
后,使用connect(&app,&QtSingleApplication::messageReceived,&w,&MainWindow::messageHandle)
连接。