Я думаю, вы ищете сигнал QMenu::aboutToShow
. Этот сигнал испускается, когда пользователь открывает меню, и это идеальный момент для повторного заполнения вашего меню.
Тем не менее, вы должны принять во внимание следующее:
Сигнал излучается синхронно относительно остальной части пользовательского интерфейса, это означает, что как только слот, обрабатывающий его, завершит работу, появится меню. Таким образом, вы должны заполнить меню, прежде чем вернуться из этой функции.
Этот сигнал испускается в главном потоке (тот, который обрабатывает GUI), поэтому остальная часть интерфейса будет заблокирована до его завершения. Это важно, если ваши сетевые подключения зависят от цикла событий. Вы можете использовать QApplication::processEvents
, чтобы убедиться, что события потребляются.
Базовый пример
В следующем примере ради простоты используется таймер вместо сетевого подключения, но он иллюстрирует мою точку зрения:
В некоторой функции инициализации (такой как конструктор). Предполагается, что меню уже существует (аналогично случаю контекстного меню):
connect(ui.menuDynamicMenu, &QMenu::aboutToShow, this, &MainWindow::onMenuAboutToShow);
Слот (m_waiting
должен быть атомным логическим или аналогично защищенным флагом, в случае, если вы хотите обрабатывать сетевое соединение, используя многопоточность):
void MainWindow::onMenuAboutToShow()
{
// Here your _synchronous_ network query
// Probably you'll have to use some kind of barrier
m_waiting = true;
QTimer::singleShot(2000, this, [this]() {
ui.menuDynamicMenu->clear();
ui.menuDynamicMenu->addAction("Some action from network query");
ui.menuDynamicMenu->addAction("Another action from network query");
m_waiting = false;
});
while (m_waiting) {
qApp->processEvents(QEventLoop::WaitForMoreEvents);
}
}
Полный код этого примера доступен в GitHub .