当Qt应用只允许启动一个实例时,可以使用QSingleApplication来实现。
QSingleApplication是Qt提供的一个qt-solution,它不包含在Qt的library中,相关例程卡参考其对应目录下的doc和example。
本文介绍的SingleApplication,是在Qt5中对QtSingleApplication的替换,它保留应用程序的主实例并终止每个后续实例,同时它也可以(如果启用)生成辅助实例(与主实例无关),并可以从辅助实例向主实例发送数据。
SingleApplication使用
SingleApplication类可通过宏变量QAPPLICATION_CLASS
来设置其继承自QCoreApplication
或QApplication
(默认是QCoreApplication
)。
类库中使用了QLocalServer
和QSharedmemory
块。应用程序的第一个实例为主实例,它会检查共享内存块是否存在,如不存在则会启动一个QLocalServer
来监听连接。每个后续实例会去检测共享内存是否存在,如存在,它将连接到QLocalServer,并通知主实例启动了一个新实例,之后会已状态0终止实例。在主实例中,SingleApplication将发出instanceStarted()
信号,即检测到新实例已经启动。
例子
main.cpp
#include <QApplication>
#include <SingleApplication.h>
int main( int argc, char* argv[] )
{
SingleApplication app( argc, argv );
return app.exec();
}
在pro文件中添加
include(singleapplication/singleapplication.pri)
DEFINES += QAPPLICATION_CLASS=QApplication
# DEFINES += QAPPLICATION_CLASS=QCoreApplication
Instance Started信号
SingleApplication类实现了一个instanceStarted()
信号,绑定到该信号后可以在应用程序中检测是否有新实例正在启动,如
// window is a QWindow instance
QObject::connect(
&app,
&SingleApplication::instanceStarted,
&window,
&QWindow::raise
);
辅助实例
如果想要启动额外的辅助实例(与主实例无关),需要启用SingleApplicaion
构造函数的第三个参数,该参数默认为false,意味着没有辅助实例。下面例子给出了如何启动一个辅助实例并通过命令行参数向主实例发送信息,然后在关闭。
int main(int argc, char *argv[])
{
SingleApplication app( argc, argv, true );
if( app.isSecondary() ) {
app.sendMessage( app.arguments().join(' ')).toUtf8() );
app.exit( 0 );
}
return app.exec();
}
注:辅助实默认不会触发instanceStarted()
信号。可以通过以下方式来区分主实例和辅助实例:
app.isPrimary();
// or
app.isSecondary();
注:如果主实例终止后,即使在辅助实例已经设置的情况下,新启动的实例会替代主实例。
API
成员函数
SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSecondary = false, Options options = Mode::User, int timeout = 100 )
构造函数
bool SingleApplication::sendMessage( QByteArray message, int timeout = 100 )
向主实例发送信息。
bool SingleApplication::isPrimary()
是否为主实例。
bool SingleApplication::isSecondary()
是否为辅助实例
quint32 SingleApplication::instanceId()
返回当前实例的ID号。
qint64 SingleApplication::primaryPid()
返回主实例ID。
QString SingleApplication::primaryUser()
返回运行主实例的用户名。
QString SingleApplication::currentUser()
返回运行当前实例的用户名。
信号
void SingleApplication::instanceStarted()
新实例启动时触发,辅助实例设置为
Mode::SecondaryNotification
标记时不触发。
void SingleApplication::receivedMessage( quint32 instanceId, QByteArray message )
从辅助实例接受信息。