4

I want to add, submenu to a menu item dynamically. How can I achive this?

I tried like this, I have created an Action and submenu. Then I have added the submenu to action. But, I have connected the “triggered” signal of action. its getting crash if I click on the action..

I have also handled the “aboutToShow” signal of menu, same its also getting crash when I click on action..

Here is the sampe code.

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

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

                 menubar()->addAction(test);

I want to get the notification, before the display of submenu..

additonal information:

pleas try this code, in your main window constructor.

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);

if I do like this, I am able to see one submenu item. But before that Move slot should call, its not getting called.. and even before hide also the same slot should call.. its not coming..

I tried the return values of connect.. its true only… so what is wrong with my code.. please say..

Naruto
  • 9,476
  • 37
  • 118
  • 201

2 Answers2

3

Such code should work:

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

I think addMenu() addAction() should work in more reliable way. This approach works for me.

VestniK
  • 1,910
  • 2
  • 17
  • 29
  • Thanks, but my problem is, i am able to add the submenu's. i want to change the submenu dynamically.. some time i require to add more submenu some time less.. in that case, when user click on the main menu, which has submenu, it should emit "aboutToShow" signal and gets connect to slot. but in runtime if i click on mainmenu.. the app is crashing – Naruto May 06 '10 at 13:19
  • 1
    So you want to repopulate menu each time it's opened am I understand you correctly? Are you deleting previous actions of the menu in the move() function? – VestniK May 06 '10 at 14:05
  • NO.. i dont want to populate any menu...just add the code added below the "additional information" and try in mainwindow constructor..see the behaviour..am not getting why "abouttoshow" signal is being emitted. could you please check once.. is it bug? or i am missing sme thing – Naruto May 07 '10 at 04:10
  • I've just tried to create new project. I created class derived from QMainWindow added your code absolutely without changes and created Move slot with the code: qDebug("Moved"); Application works as expected. Nothing is crashes and I see "Moved" text on the console every time menu is shown or hidden. Your problem is not in the code you've posted. – VestniK May 07 '10 at 06:41
  • which platform are you trying? Symbian,or desktop? – Naruto May 07 '10 at 07:00
  • are you using symbina, are you able to move to the "Move" slot? i mean, are you going to "Move" slot.. try in debig mode, put a message box in "Move" slot – Naruto May 07 '10 at 07:03
  • I've tried to run the code on my Linux desktop (Kubuntu 10.04 Qt 4.6.2). As I said I have created Move() slot in my QMainWindow subclass which just prints "Moves" line into the terminal. Code was working exactly as expected. – VestniK May 07 '10 at 08:56
2

I'm not sure to understand exactly what you're willing to do into your Move() slot.

But here is your own code (I removed what seemed useless to me), modified so that it is not crashing on my computer :

mainwindow.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

mainwindow.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);
}

I don't know exactly what you want to do into your Move() slot, but as an example, each time the Move() slot is called, a new submenu item is added.

Hope this helps.

Jérôme
  • 26,567
  • 29
  • 98
  • 120
  • Yes, i have tried it in my nokia emulator.. it works well with out crash, but the submenu "Test" is not getting added when i click on Test main menu.. i mean to say,aboutToShow() signal itself not emitting.. i think its bug in Qt symbian.. which version of Qt are you using? and what environment are you using? Desktop or mobile? – Naruto May 07 '10 at 08:46
  • I think you should post a bug to Qt issue tracker http://bugreports.qt.nokia.com if you think that it's a bug in Symbian implementation of Qt. I already had such experience and can say that Nokia support engineers are quite friendly. – VestniK May 07 '10 at 09:05
  • Thanks, ya.. you are right, they are.. i have posted a bug too, i will update you on this once i get any update from them – Naruto May 07 '10 at 09:11
  • I'm using Qt Creator 1.3.1, based on Qt 4.6.1, on Windows XP. – Jérôme May 07 '10 at 10:36