好吧,据我所知,使用两个或多个Q*Application
s ( QCoreApplication
, QGuiApplication
, QApplication
) 意味着:
创建第二个(或更多)应用程序时,断言在调试模式下失败。发布模式下没有崩溃。
更新单例的每个实例化Q*Application
(即,qApp
将始终指向最后一个实例)。
应用程序名称和版本等全局属性随实例传输并覆盖以前的属性。
任何连接到 a 插槽的信号都会Q*Application
调用单例的插槽,即使在创建最新实例之前连接也是如此。
只有连接到最新信号的槽Q*Application
才会被调用(它们不会被转移到新实例)。
创建新Q*Application
实例时不会传输转换器。
如果最后一个Q*Application
被销毁,则单例变为空(它不会回退到前一个实例)。
您可以使用以下代码和切换来测试这些功能USE_TWO_QAPPS
:
#include <QtCore>
#define USE_TWO_QAPPS
int main(int argc, char* argv[])
{
QTranslator tr1;
QCoreApplication a1(argc, argv);
a1.setApplicationName("a1");
a1.installTranslator(&tr1);
qDebug() << qApp << &a1;
qDebug() << "a1.applicationName() =" << a1.applicationName();
// qApp == &a1
QObject::connect(&a1, &QCoreApplication::aboutToQuit, []() {
// point 5, never called with Q*Application
qDebug() << "Hello world from a1!";
});
QTimer::singleShot(2000, &a1, &QCoreApplication::quit); // as if connected to latest qApp, point 4
#ifdef USE_TWO_QAPPS
// if (true) { // uncomment to test point 7
QCoreApplication a2(argc, argv);
a2.setApplicationName("a2");
qDebug() << qApp << &a1 << &a2; // test point 2
qDebug() << "a2.applicationName() =" << a2.applicationName();
qDebug() << "a1.applicationName() =" << a1.applicationName(); // as if called from qApp, point 3
QObject::connect(&a2, &QCoreApplication::aboutToQuit, []() {
qDebug() << "Hello world from a2!";
});
// } // uncomment to test point 7
#endif
qDebug() << qApp->removeTranslator(&tr1); // false if the translator is not installed, point 6
a1.installTranslator(&tr1); // it is installed in the latest instance (as if called from qApp)
qDebug() << qApp->removeTranslator(&tr1);
return qApp->exec();
}
结果与一个Q*Application
QCoreApplication(0xfafb74) QCoreApplication(0xfafb74)
a1.applicationName() = "a1"
真的
真的
你好,来自 a1 的世界!
结果有两个Q*Application
QCoreApplication(0xbefb2c) QCoreApplication(0xbefb2c)
a1.applicationName() = "a1"
QCoreApplication 中的 ASSERT 失败:“应该只有一个应用程序对象”,文件 ########\qtbase\src\corelib\kernel\qcoreapplication.cpp,第 769 行
QCoreApplication(0xbefb1c) QCoreApplication(0xbefb2c) QCoreApplication(0xbefb1c)
a2.applicationName() = "a2"
a1.applicationName() = "a2"
错误的
真的
你好,来自 a2 的世界!
当测试点7,a2
退出if
语句时被销毁。在这种情况下,每次调用Q*Application
完成的方法都会引发警告并且不会被执行(它们不会崩溃并且没有断言被破坏)。即使从以前的应用程序调用时也会发生这种情况:a1.installTranslator(&tr1);
QApplication::installTranslator: 请先实例化QApplication对象
注意:使用 Visual Studio 2010 测试。Qt 版本为 4.7 和 5.6.1-1,两者结果相同
更新:https://github.com/cbuchart/stackoverflow/blob/master/46304070-multiple-qapplication-instances/main.cpp中提供了此答案的更简洁的代码版本
在注释之后,此代码还测试了当所有QApplication
对象被销毁然后再次创建时会发生什么。结果:正如预期的那样,没有发生任何特殊情况,似乎没有副作用。
结论
考虑到这些点,似乎可以与两个或多个一起工作,Q*Application
更关键的是,当在任何一个但最后一个上完成时Q*Application
,与信号的连接会丢失并且没有安装翻译器。此外,如果最后一个实例被销毁,则没有可用的应用程序,因此您应该注意这些情况(例如,如果卸载创建最后一个实例的 DLL)。