Динамическая настройка содержимого меню в Qt - PullRequest
0 голосов
/ 08 апреля 2019

Я хочу создать меню, содержимое которого определяется динамически (через некоторые данные, полученные из сети). Как мне реализовать такое меню в Qt?

Сеть должна запрашивать содержимое для отображения при каждом открытии меню.

Ответы [ 2 ]

0 голосов
/ 09 апреля 2019

Я думаю, вы ищете сигнал 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 .

0 голосов
/ 08 апреля 2019

при условии, что у вас где-то есть строка меню:

QMenu* m = new QMenu(this);
m->setTitle("click here");
m->setIcon(QIcon());
ui->menuBar->addMenu(m);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...