首页 > 解决方案 > 在 Qt 中动态设置菜单的内容

问题描述

我想创建一个菜单,其内容是动态确定的(通过从网络接收的一些数据)。我将如何在 Qt 中实现这样的菜单?

每当打开菜单时,都应向网络查询要显示的内容。

标签: c++qtuser-interfacemenusignals

解决方案


我认为您正在寻找QMenu::aboutToShow信号。当用户打开菜单时会发出此信号,这是重新填充菜单的最佳时机。

但是,您必须考虑以下事项:

  • 信号是同步发出的,与 UI 的其余部分有关,这意味着一旦插槽处理完成,将显示菜单。因此,您必须在从该功能返回之前填充菜单。

  • 此信号在主线程(处理 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中找到。


推荐阅读