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
затем могут быть представления для данных, представленных контроллером.