0

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

emit updateMainMenuAccordingToUserRights;

QCoreApplication::processEvents();

emit jumpMainMenu();

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

感谢您的任何建议。

4

1 回答 1

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;
}

一个函数(理想情况下在控制器类中)然后将通过对象松散地耦合LoginScreen到:MenuScreenLoginData

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();
};

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

于 2018-03-28T00:10:58.400 回答