- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我想知道在同一个进程中有多个 QApplication
/QCoreApplication
实例有什么影响(问题),以及如何解决一些相关问题.
场景如下:我想在开源第三方应用程序上制作一个包装器,以便将其转换为可嵌入的小部件作为可选插件(该应用程序基本上由单个 QMainWindow 组成基于
的接口(interface))。
此类项目严重依赖于 QCoreApplication
派生类,但主要是因为它被用作已经存在的单例。我能够修改代码(我必须这样做才能将 QMainWindow
公开为可嵌入的小部件),尽管由于该项目的复杂性,我不能简单地删除 父类。
因此,最终应用程序将拥有自己的QApplication
(在启动时创建),然后可选择加载上述插件(从而创建第二个QCoreApplication
)。只有第一个(主)QApplication
用于事件循环(QCoreApplication::exec()
)。
我知道 QCoreApplication
是一个单例。在我的测试中,单例总是指向最后创建的实例:
qDebug() << qApp;
auto app1 = new QApplication(argc, argv);
qDebug() << qApp;
auto app2 = new TheOtherQApplication(argc, argv);
qDebug() << qApp;
输出是
QObject(0x0)
QApplication(0x6f9400, name = "test")
ASSERT failure in QCoreApplication: "there should be only one application object", file kernel\qcoreapplication.cpp, line 595
TheOtherQApplication(0x2550dc0, name = "test")
TheOtherQApplication(0x2550dc0, name = "test") TheOtherQApplication(0x2550dc0, name = "test")
可以看出,在创建第二个QApplication
后,它替换了全局实例。有什么办法可以解决这个问题吗?由于该插件是可选的,因此显而易见的答案(加载主要的 QApplication
在第二位)不是一个合适的选择。
此外,拥有多个 QApplication
实例是否还有其他影响?还是都和事件循环(勾选)和单例有关?
注意:由于第三方依赖尚未完全更新,这是一个基于 Qt 4.7 的项目。计划在一年左右迁移到最新版本,但目前我必须处理 4.7。
顺便说一句,我已经回顾了几个相关问题,包括 this one但这并没有提供任何有用的信息。
最佳答案
嗯,据我所知,使用两个或多个Q*Application
(QCoreApplication
、QGuiApplication
、 QApplication
) 意味着:
创建第二个(或更多)应用程序时,断言在 Debug模式下失败。 Release模式下没有崩溃。
Q*Application
的每个实例都会更新单例(即,qApp
将始终指向最后一个实例)。
应用程序名称和版本等全局属性随实例传输并覆盖之前的属性。
连接到 Q*Application
槽的任何信号都会调用单例槽,即使在创建最新实例之前已连接也是如此。
只有连接到最新 Q*Application
信号的槽才会被调用(它们不会转移到新实例)。
创建新的 Q*Application
实例时,不会传输翻译器。
如果最后一个 Q*Application
被销毁,则单例变为 null(它不会回退到前一个实例)。
您可以使用以下代码并切换 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"
true
true
Hello world from a1!
两个Q*Application
的结果
QCoreApplication(0xbefb2c) QCoreApplication(0xbefb2c)
a1.applicationName() = "a1"
ASSERT failure in QCoreApplication: "there should be only one application object", file ########\qtbase\src\corelib\kernel\qcoreapplication.cpp, line 769
QCoreApplication(0xbefb1c) QCoreApplication(0xbefb2c) QCoreApplication(0xbefb1c)
a2.applicationName() = "a2"
a1.applicationName() = "a2"
false
true
Hello world from a2!
在测试点 7 时,a2
在退出 if
语句时被销毁。在这种情况下,每次调用 Q*Application
方法都会引发警告并且不会执行(它们不会崩溃并且没有断言被破坏)。即使从以前的应用程序调用时也会发生这种情况:a1.installTranslator(&tr1);
QApplication::installTranslator: Please instantiate the QApplication object first
注意:使用 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)。
关于c++ - 多个 QApplication 实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46304070/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!