QEventLoop обрабатывает все события

У меня есть экран меню, который должен быть обновлен до закрытия экрана входа. Код похож на приведенный ниже;

emit updateMainMenuAccordingToUserRights;

QCoreApplication::processEvents();

emit jumpMainMenu();

Проблема в том, "как я могу быть уверен, что все события обработаны?". Поскольку некоторые из слотов, запускаемых сигналом updateMainMenuAccordingToUserRights, добавляют новые события в цикл событий для обновления компонентов представления. Прежде чем перейти в главное меню, я должен быть уверен, что оно уже обновлено. Я немного искал и видел, что QCoreApplication::processEvent обрабатывает цикл всего один раз. Хорошо, это причина, по которой вышеприведенный код не работает. Даже я попробовал некоторые методы QEventLoop, но не смог решить эту проблему.

Спасибо за любой совет.

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 в MenuScreen свободно через LoginData объект:

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

В идеале вам нужно иметь отдельный класс контроллера для реализации логики, а не на экранах. LoginScreen а также MenuScreen затем могут быть представления для данных, представленных контроллером.

Другие вопросы по тегам