简体   繁体   English

QEventLoop处理所有事件

[英]QEventLoop process all events

I've a menu screen which must be updated before the login screen closed. 我有一个菜单屏幕,必须在登录屏幕关闭之前进行更新。 The code is something similar to below one; 代码类似于下面的代码。

emit updateMainMenuAccordingToUserRights;

QCoreApplication::processEvents();

emit jumpMainMenu();

The problem is 'how can I be sure that all events have been processed?'. 问题是“如何确定所有事件均已处理?”。 Because some of the slots triggered by updateMainMenuAccordingToUserRights signal adds new events to the event loop to update view components. 因为updateMainMenuAccordingToUserRights信号触发的某些插槽将新事件添加到事件循环中,以更新视图组件。 Before jumping main menu I must be sure that it's already updated. 在跳转主菜单之前,我必须确保它已经被更新。 I've searched a little and seen that QCoreApplication::processEvent process the loop for just once. 我搜索了一下,发现QCoreApplication :: processEvent仅处理一次循环。 Okay, that's the reason why the above code does not work. 好的,这就是上面的代码不起作用的原因。 Even I tried some QEventLoop methods but couldn't manage to solve this problem. 即使我尝试了一些QEventLoop方法,也无法解决此问题。

Thanks for any advice. 感谢您的任何建议。

I've a menu screen which must be updated before the login screen closed 我有一个菜单屏幕,必须在登录屏幕关闭之前进行更新

Not at all - it's an XY problem. 完全没有-这是一个XY问题。 In other words: your design is wrong. 换句话说:您的设计是错误的。 You need to lightly couple the login screen somehow to the menu screen, so that the menu screen gets the information it needs to update itself, before the login screen is closed. 您需要以某种方式将登录屏幕轻轻地耦合到菜单屏幕,以便菜单屏幕获得在关闭登录屏幕之前需要更新的信息。 At any point after that, the login screen can indeed close. 在此之后的任何时候,登录屏幕确实可以关闭。

Most likely you're tightly coupling the login screen with login controller , and thus the LoginScreen class should emit the event that the MenuScreen will process. 您很可能将登录屏幕与登录控制器紧密耦合,因此LoginScreen类应该发出MenuScreen将处理的事件。

Your current signal names suggest very tight coupling between the screens. 您当前的信号名称表明屏幕之间的耦合非常紧密。 There is just one signal that you need: loginDone(const LoginData &) , where LoginData is a structure/class that carries the information about the logged in user etc. 您只需要一个信号: loginDone(const LoginData &) ,其中LoginData是一个结构/类,用于承载有关已登录用户等的信息。

Then, the three lines of code from the question simply become: 然后,问题中的三行代码就变成了:

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

and

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

A function (ideally in a controller class) would then couple the LoginScreen to MenuScreen loosely via the LoginData object: 然后,一个函数(最好在控制器类中)将通过LoginData对象将LoginScreenMenuScreen松散耦合:

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

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

Ideally, you'd want to have a separate controller class to implement the logic, instead of having it in screens. 理想情况下,您希望有一个单独的控制器类来实现逻辑,而不是将其显示在屏幕中。 The LoginScreen and MenuScreen could then be views for the data exposed by the controller. 然后, LoginScreenMenuScreen可以是控制器公开的数据的视图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM