【问题标题】:how to add menu dynamically in Qt如何在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 之前,同一个插槽也应该调用..它不会来..

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

【问题讨论】:

    标签: qt qt4 menu symbian nokia


    【解决方案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。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-18
    相关资源
    最近更新 更多