【问题标题】:Dynamically setting the content of a menu in Qt在 Qt 中动态设置菜单的内容
【发布时间】:2019-08-29 17:26:51
【问题描述】:

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

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

【问题讨论】:

    标签: c++ qt user-interface menu signals


    【解决方案1】:

    假设您在某处有一个菜单栏:

    QMenu* m = new QMenu(this);
    m->setTitle("click here");
    m->setIcon(QIcon());
    ui->menuBar->addMenu(m);
    

    【讨论】:

    • 菜单可以在运行时通过类调用轻松设置。只需将网络线程与 GUI 分开,以便 GUI 始终保持响应。
    【解决方案2】:

    我认为您正在寻找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 中找到。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-29
      • 2014-03-24
      • 2014-09-12
      • 2023-02-24
      • 1970-01-01
      • 1970-01-01
      • 2020-08-10
      • 1970-01-01
      相关资源
      最近更新 更多