完全删除 QApplication 实例并在另一个线程中重新创建它

Posted

技术标签:

【中文标题】完全删除 QApplication 实例并在另一个线程中重新创建它【英文标题】:Totally deleting the QApplication Instance and recreating it in another thread 【发布时间】:2017-03-30 07:54:26 【问题描述】:

我怎样才能完全删除 QApplication 实例,以便可以在剪切库中重新创建它。 如果我有这样的代码:

int main(int argc, char ** argv) 
QApplication *app = new QApplication(argc, argv);
MyWindow dialog;
dialog.show();
app->exec();
return 0

我希望能够在退出应用程序后删除实例(在 app.exec() 之后关闭应用程序) 我已尝试执行以下操作:

app->setQuitOnLastWindowClosed(false);
app->quit();
delete app;

但没有一个可以工作。我想像以前没有创建的那样删除 QApplication 实例。 如果我没有在 main 中定义 QApplication,我的共享库中的 QApplication 总是可以工作的。

    库 (lib) 和主应用程序 (app) 使用不同的 Qt 副本。 我正在开发应用程序,库已导入到我的应用程序中。 关闭第一个对话框后,我正在使用一个事件来触发它正在等待此事件的库中的线程。

【问题讨论】:

据我所知你不能。 QApplication 使用 static 或在程序退出之前一直存在的全局变量。 【参考方案1】:

您不需要这样做,因为QApplication 只能在主线程中创建。如果库和主可执行文件共享同一个 Qt 库,可能主应用程序已经创建了 QApplication 对象并将为您运行事件循环。所以你在库中唯一需要做的就是创建一些对象,事件循环会处理它们的事件。

如果主可执行文件不使用 Qt,那么您应该在主线程中创建应用程序,启动其事件循环,并让本机事件循环为您分派事件。

唉,直接回答你的问题:大概你想在app.exec() 返回后做一些事情。那么你的代码可能就是:

int main(int argc, char ** argv) 
  
     QApplication appargc, argv;
     MyWindow dialog;
     dialog.show();
     app.exec();
   
   doSomething();

如果我关闭第一个对话框,将离开事件循环。是否可以保持事件循环?

是的。您可以清除第一个对话框的Qt::WA_QuitOnClose 属性。或者,最好将其设置在您的对话框中 - 只要有任何带有QT::WA_QuitOnClose 的对话框仍然打开,应用程序就不会退出。

因此,对于第二个对话框,调用:

secondDialog->setAttribute(Qt::WA_QuitOnClose);

或者,如果您没有指向对话框的指针,则可以迭代所有***小部件并清除(或设置)所有小部件的属性:

for (auto widget : qApp->topLevelWidgets())
  widget->setAttribute(Qt::QA_QuitOnClose, false);

【讨论】:

我想做的是执行一个对话框,做一些事情,然后关闭它。然后使用库中的另一个对话框(它已经创建了 QApplication 对象和 app.exec)。如果我关闭第一个对话框,将留下事件循环。那么是否可以保留事件循环,以便我可以从库中删除创建 QApplication 和 exec ?或者如果有办法从主目录中删除 QApplication 对象,以便在关闭对话框后使用库中的 QApplication?正如我所说,在主目录中根本不使用 QApplication,库中的对象已正确初始化。跨度> Kuba:关于保持事件循环,你肯定是对的。但是我无法启动新的对话框。我可以使用 QApplication 实例单独启动每个人,但我无法使用同一个实例,也无法重新创建新实例。我需要完全关闭第一个对话框,然后打开另一个(不应该在一起,一次只有一个)。如果我在初始化另一个实例之前从内存中完全删除第一个实例会很好,或者你有其他方法吗? 请编辑问题以回答以下问题: 1. 库 (lib) 和主应用程序 (app) 是否使用相同的 Qt 副本? 2.你是app和lib的开发者吗? 3. 什么触发了第二个对话框的显示? 4. 展示一个模拟应用程序和库来演示您正在尝试做的事情。我们总共讨论了 40 行代码,可能跨越两个 .cpp 文件。去做吧。

以上是关于完全删除 QApplication 实例并在另一个线程中重新创建它的主要内容,如果未能解决你的问题,请参考以下文章

我扩展 QApplication 并在 exec_ 后调用一个方法不起作用

如何使控制器在单击时插入时间并在另一次单击时删除时间?

unity脚本中变量在另一个脚本如何调用

将表单输入存储为局部变量并在另一个网页中使用

在反应链接中使用参数并在另一个组件中获取它的值?

多个 QApplication 实例