QEventLoop 处理所有事件

Posted

技术标签:

【中文标题】QEventLoop 处理所有事件【英文标题】:QEventLoop process all events 【发布时间】:2018-09-06 09:45:03 【问题描述】:

我有一个菜单屏幕,必须在登录屏幕关闭之前更新。 代码类似于下面的代码;

emit updateMainMenuAccordingToUserRights;

QCoreApplication::processEvents();

emit jumpMainMenu();

问题是“我如何确定所有事件都已处理?”。因为由 updateMainMenuAccordingToUserRights 信号触发的一些槽将新事件添加到事件循环以更新视图组件。在跳转主菜单之前,我必须确保它已经更新。我搜索了一下,发现 QCoreApplication::processEvent 只处理循环一次。好的,这就是上面代码不起作用的原因。即使我尝试了一些 QEventLoop 方法,但无法解决这个问题。

感谢您的建议。

【问题讨论】:

您需要在主菜单中添加一个信号,一旦更新完成就会触发一个槽。在此插槽中,您发出函数调用jumpMainMenu QEventLoop::WaitForMoreEventsflag你试过了吗。 但就我而言,主菜单由小插件组成。主菜单不仅仅是一个对象。它正在被应用程序的一小部分更改(每个插件中都有一个用于 updateMainMenuAccordingToUserRights 的插槽)。所以,所有这些插槽都应该被执行。甚至这些插槽也可以自己添加新事件/发出信号。 @MohammadKanan 是的,我已经尝试过了。 必须强制事件循环意味着您可能正在做一些不推荐的事情,并且可以以更好的方式完成。我已经广泛使用 Qt 10 年了,我用它做了一些疯狂的复杂的事情,而且我从来不需要强制事件处理,一次也没有。 【参考方案1】:

我有一个菜单屏幕,必须在登录屏幕关闭之前更新

完全没有 - 这是一个 XY 问题。换句话说:你的设计是错误的。您需要以某种方式轻轻地将登录屏幕耦合到菜单屏幕,以便菜单屏幕在登录屏幕关闭之前获取它需要更新自身的信息。在那之后的任何时候,登录屏幕确实可以关闭。

您很可能将登录屏幕 与登录控制器 紧密耦合,因此LoginScreen 类应该发出MenuScreen 将处理的事件。

您当前的信号名称表明屏幕之间的耦合非常紧密。您只需要一个信号:loginDone(const LoginData &),其中LoginData 是一个结构/类,其中包含有关登录用户等的信息。

那么,问题中的三行代码就变成了:

auto d = this->getLoginData();
emit loginDone(d);
close();

LoginData LoginScreen::getLoginData() const 
  LoginData d;
  d.foo = this->foo();
  d.bar = this->bar();
  ...
  return d;

然后,一个函数(最好在控制器类中)将通过 LoginData 对象松散地将 LoginScreen 耦合到 MenuScreen

void setLoginDataOnMenu(const LoginData &data, MenuScreen *menu) 
  ...
  menu->show();
;

int main(int argc, char **argv) 
  QApplication appargc, argv;
  LoginScreen login;
  MenuScreen menu;
  QObject::connect(&login, &LoginScreen::loginDone, &menu, [&](const LoginData &)
    setLoginDataOnMenu(data, &menu);
  );
  login.show();
  return app.exec();
;

理想情况下,您希望有一个单独的控制器类来实现逻辑,而不是在屏幕中。然后LoginScreenMenuScreen 可以是控制器公开的数据的视图。

【讨论】:

以上是关于QEventLoop 处理所有事件的主要内容,如果未能解决你的问题,请参考以下文章

关于Qt的事件循环以及QEventLoop的简单使用(QEventLoop::quit()能够终止事件循环,事件循环是可以嵌套的)

QEventLoop 仅等待本地事件而不是主循环事件

Qt ------ 主事件循环与 QEventLoop

QEventLoop等待另外一个事件的停止,非常实用 good

Qt库事件循环问题

QEventLoop 的使用两例