如何在Qt中动态添加菜单

Posted

技术标签:

【中文标题】如何在Qt中动态添加菜单【英文标题】:how to add menu dynamically in Qt 【发布时间】:2010-05-06 12:51:08 【问题描述】:

我想动态地将子菜单添加到菜单项。我怎样才能做到这一点?

我试过这样, 我创建了一个动作和子菜单。然后我将子菜单添加到操作中。 但是,我已经连接了动作的“触发”信号。如果我单击该操作,它会崩溃..

我还处理了菜单的“aboutToShow”信号,当我点击动作时它也会崩溃..

这里是示例代码。

Submenu = new QMenu(this);      
connect(Submenu, SIGNAL( aboutToShow()), this, SLOT(move ()));

                  QAction *test = new QAction(tr("Selection"), this);
                  test ->setMenu(Submenu);

                 menubar()->addAction(test);

我想在子菜单显示之前得到通知..

附加信息:

请在您的主窗口构造函数中尝试此代码。

QAction *action = new QAction("Test",this);
QAction *dummyaction = new QAction("Testing",this);
QMenu *menu = new QMenu();
menu->addAction(dummyaction);

bool val= connect(menu, SIGNAL( aboutToShow()), this, SLOT( Move()));
val= connect(menu, SIGNAL( aboutToHide()), this, SLOT(Move()));

action->setMenu(menu);
this->menuBar()->addAction(action);

如果我这样做,我可以看到一个子菜单项。但是在 Move 插槽应该调用之前,它没有被调用..甚至在 hide 之前,同一个插槽也应该调用..它不会来..

我尝试了连接的返回值..它只是真实的......所以我的代码有什么问题..请说..

【问题讨论】:

【参考方案1】:

这样的代码应该可以工作:

QMainWindow wnd;
QAction *act = wnd.menuBar()->addMenu("SomeMenu")->addMenu("someSubmenu")->addAction("someAction");
QObject::connect(act,SIGNAL(triggered()),
                 someObj,SLOT(actionReaction()));

我认为 addMenu() addAction() 应该以更可靠的方式工作。这种方法对我有用。

【讨论】:

谢谢,但我的问题是,我可以添加子菜单。我想动态更改子菜单..有时我需要更少的时间添加更多子菜单..在这种情况下,当用户单击具有子菜单的主菜单时,它应该发出“aboutToShow”信号并连接到插槽.但在运行时,如果我点击主菜单.. 应用程序崩溃 所以你想在每次打开菜单时重新填充菜单,我理解正确吗?您是否在 move() 函数中删除菜单的先前操作? NO.. 我不想填充任何菜单...只需添加添加到“附加信息”下方的代码并在主窗口构造函数中尝试..查看行为..我不明白为什么“即将显示” " 正在发出信号。你能检查一次吗..是错误吗?或者我错过了一些东西 我刚刚尝试创建新项目。我创建了从 QMainWindow 派生的类,完全没有更改地添加了您的代码,并使用代码创建了 Move 插槽: qDebug("Moved");应用程序按预期工作。没有什么是崩溃的,每次显示或隐藏菜单时,我都会在控制台上看到“已移动”文本。您的问题不在您发布的代码中。 您在尝试哪个平台? Symbian 还是桌面?【参考方案2】:

我不确定你愿意在Move() 插槽中做什么。

但这是您自己的代码(我删除了对我来说似乎无用的代码),经过修改使其不会在我的计算机上崩溃:

ma​​inwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

#include <QAction>
#include <QMenu>

class MainWindow : public QMainWindow

   Q_OBJECT

public:
   explicit MainWindow(QWidget *parent = 0);

private:
   QMenu* menu;
   QAction *dummyaction;
   QMenu* m_pSubMenu;
 private slots:
    void Move();
;

#endif // MAINWINDOW_H

ma​​inwindow.cpp:

#include "mainwindow.h"

#include <QMenuBar>

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)

   m_pSubMenu = NULL;
   QMenuBar* pMenuBar = new QMenuBar(this);

   setMenuBar(pMenuBar);

   dummyaction = new QAction("Testing",this);
   menu = new QMenu("Test", this);
   menu->addAction(dummyaction);
   this->menuBar()->addMenu(menu);

   connect(menu, SIGNAL(aboutToShow()), this, SLOT(Move()));


void MainWindow::Move() 
   if (!m_pSubMenu) 
      m_pSubMenu = new QMenu(menu);
      dummyaction->setMenu(m_pSubMenu);
   
   QAction* pAction = new QAction("Test", this);
   m_pSubMenu->addAction(pAction);

我不确切知道您想在 Move() 插槽中做什么,但例如,每次调用 Move() 插槽时,都会添加一个新的子菜单项。

希望这会有所帮助。

【讨论】:

是的,我已经在我的诺基亚模拟器中尝试过了。它运行良好而不会崩溃,但是当我点击测试主菜单时,子菜单“测试”没有被添加。我的意思是说,aboutToShow() 信号本身没有发出..我认为它在 Qt symbian 中的错误..您使用的是哪个版本的 Qt?你使用的是什么环境?台式机还是移动设备? 如果您认为这是 Symbian 的 Qt 实现中的错误,我认为您应该将错误发布到 Qt 问题跟踪器 bugreports.qt.nokia.com。我已经有过这样的经验,可以说诺基亚支持工程师非常友好。 谢谢,你是对的,他们是.. 我也发布了一个错误,一旦我从他们那里得到任何更新,我会更新你 我在 Windows XP 上使用基于 Qt 4.6.1 的 Qt Creator 1.3.1。

以上是关于如何在Qt中动态添加菜单的主要内容,如果未能解决你的问题,请参考以下文章

QT:如何在布局中动态添加和删除小部件?

如何在VB运行中动态添加菜单项目?

如何在VB运行中动态添加菜单项目?

c#中如何动态添加菜单项并实现其点击?

如何在mfc中动态添加子菜单

Qt中QTabWidget动态添加页面的问题