Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. Adapting QStringList to "two level" array
QtWS25 Last Chance

Adapting QStringList to "two level" array

Scheduled Pinned Locked Moved Unsolved C++ Gurus
10 Posts 3 Posters 1.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Anonymous_Banned275
    wrote on last edited by
    #1
    This post is deleted!
    JonBJ 1 Reply Last reply
    0
    • A Anonymous_Banned275

      This post is deleted!

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #2

      @AnneRanch
      You have a (C) array of QStringLists in your list_array.

      list_array[0] is the first QStringList, list_array[1] is the second, etc. Each QStringList has its own length/size/number of strings.
      list_array[0].size() is the size/length of the first bunch (9).
      list_array[1].size() is the size/length of the first bunch (4).

      for (int i = 0; i < 10; i++)
          qDebug() << i << list_array[i].size();
      
      A 2 Replies Last reply
      1
      • JonBJ JonB

        @AnneRanch
        You have a (C) array of QStringLists in your list_array.

        list_array[0] is the first QStringList, list_array[1] is the second, etc. Each QStringList has its own length/size/number of strings.
        list_array[0].size() is the size/length of the first bunch (9).
        list_array[1].size() is the size/length of the first bunch (4).

        for (int i = 0; i < 10; i++)
            qDebug() << i << list_array[i].size();
        
        A Offline
        A Offline
        Anonymous_Banned275
        wrote on last edited by
        #3
        This post is deleted!
        1 Reply Last reply
        0
        • JonBJ JonB

          @AnneRanch
          You have a (C) array of QStringLists in your list_array.

          list_array[0] is the first QStringList, list_array[1] is the second, etc. Each QStringList has its own length/size/number of strings.
          list_array[0].size() is the size/length of the first bunch (9).
          list_array[1].size() is the size/length of the first bunch (4).

          for (int i = 0; i < 10; i++)
              qDebug() << i << list_array[i].size();
          
          A Offline
          A Offline
          Anonymous_Banned275
          wrote on last edited by
          #4

          @JonB I am nor sure how to ask you more about passing parameters to connect. Hopefully you will get this post and respond,

          Thanks

          JonBJ 1 Reply Last reply
          0
          • A Anonymous_Banned275

            @JonB I am nor sure how to ask you more about passing parameters to connect. Hopefully you will get this post and respond,

            Thanks

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by
            #5

            @AnneRanch
            I'm not sure what your question is. You generally do not pass extra parameters to the connect() statement. The connect() just sets up a "channel" between a signal and a slot, and is of the form:

            connect(signalObject, &SignalClass::signalMethod, slotObject, &SlotClass::slotMethod);
            

            The signal can send extra parameters via its emit, but for example if you use a Qt signal they have already specified what parameters it will pass. It is true that one can specify a lambda for the slotMethod so you can pass some extra information from the place you set up the connect(), I would not call those "parameters to connect" but perhaps that is what you are referring to.

            A 1 Reply Last reply
            2
            • JonBJ JonB

              @AnneRanch
              I'm not sure what your question is. You generally do not pass extra parameters to the connect() statement. The connect() just sets up a "channel" between a signal and a slot, and is of the form:

              connect(signalObject, &SignalClass::signalMethod, slotObject, &SlotClass::slotMethod);
              

              The signal can send extra parameters via its emit, but for example if you use a Qt signal they have already specified what parameters it will pass. It is true that one can specify a lambda for the slotMethod so you can pass some extra information from the place you set up the connect(), I would not call those "parameters to connect" but perhaps that is what you are referring to.

              A Offline
              A Offline
              Anonymous_Banned275
              wrote on last edited by
              #6
              This post is deleted!
              M 1 Reply Last reply
              0
              • A Anonymous_Banned275

                This post is deleted!

                M Offline
                M Offline
                mpergand
                wrote on last edited by mpergand
                #7

                @AnneRanch said in Adapting QStringList to "two level" array:

                I need to work on a code which gets both main menu index and current submenu index...

                It turns out that it is difficult to go up the menu hierarchy, unfortunatly.

                Here an attempt :

                QMenu menu("main menu");
                menu.addAction("action1");
                menu.addAction("action2");
                QMenu* sub=menu.addMenu("sub menu");
                sub->addAction("sub action1");
                sub->addAction("sub action2");
                menu.setAsDockMenu();
                
                QObject::connect(&menu,&QMenu::triggered,&menu,[](QAction* action)
                {
                	QString path=action->text();
                
                	QWidget* parent=action->parentWidget();
                	path+=QString("(%1)").arg(parent->actions().indexOf(action));
                
                	while(parent)
                		{
                		QMenu* menu=qobject_cast<QMenu*>(parent);
                		QString title=menu->title();
                		path+="->"+title;
                		parent=parent->parentWidget();
                
                		if(parent)
                			{
                			QMenu* menu=qobject_cast<QMenu*>(parent);
                			int index=0;
                			const QList<QAction*> actions=menu->actions();
                			for(const QAction *act : actions)
                				{
                				if(act->text()==title)
                					{
                					path+=QString("(%1)").arg(index);
                					break;
                					}
                				index++;
                				}
                			}
                		}
                
                	qDebug()<<path;
                });
                

                a click on action1 prints: "action1(0)->main menu"
                a click on sub action2 prints: "sub action2(1)->sub menu(2)->main menu"
                sub action2 is at index 1 in sub menu
                sub menu is at index 2 in the main menu

                A 1 Reply Last reply
                0
                • M mpergand

                  @AnneRanch said in Adapting QStringList to "two level" array:

                  I need to work on a code which gets both main menu index and current submenu index...

                  It turns out that it is difficult to go up the menu hierarchy, unfortunatly.

                  Here an attempt :

                  QMenu menu("main menu");
                  menu.addAction("action1");
                  menu.addAction("action2");
                  QMenu* sub=menu.addMenu("sub menu");
                  sub->addAction("sub action1");
                  sub->addAction("sub action2");
                  menu.setAsDockMenu();
                  
                  QObject::connect(&menu,&QMenu::triggered,&menu,[](QAction* action)
                  {
                  	QString path=action->text();
                  
                  	QWidget* parent=action->parentWidget();
                  	path+=QString("(%1)").arg(parent->actions().indexOf(action));
                  
                  	while(parent)
                  		{
                  		QMenu* menu=qobject_cast<QMenu*>(parent);
                  		QString title=menu->title();
                  		path+="->"+title;
                  		parent=parent->parentWidget();
                  
                  		if(parent)
                  			{
                  			QMenu* menu=qobject_cast<QMenu*>(parent);
                  			int index=0;
                  			const QList<QAction*> actions=menu->actions();
                  			for(const QAction *act : actions)
                  				{
                  				if(act->text()==title)
                  					{
                  					path+=QString("(%1)").arg(index);
                  					break;
                  					}
                  				index++;
                  				}
                  			}
                  		}
                  
                  	qDebug()<<path;
                  });
                  

                  a click on action1 prints: "action1(0)->main menu"
                  a click on sub action2 prints: "sub action2(1)->sub menu(2)->main menu"
                  sub action2 is at index 1 in sub menu
                  sub menu is at index 2 in the main menu

                  A Offline
                  A Offline
                  Anonymous_Banned275
                  wrote on last edited by Anonymous_Banned275
                  #8

                  @mpergand I am trying to modify your code and having issues. Could use some help to resolve this.

                  Here is my code snippet :

                  // modify for sumMenu
                  //subMenu[index] = subMenu[index]
                  //        ->addMenu(list[index] + " # " + QString::number(index));
                  
                  QObject::connect(&MainWindow_Bluetooth::subMenu,&QMenu::triggered,&MainWindow_Bluetooth::subMenu,[](QAction* action)
                  {// lambda
                      QString path=action->text();
                  
                  QWidget* parent=action->parentWidget();
                  path+=QString("(%1)").arg(parent->actions().indexOf(action));
                  
                  while(parent)
                      {
                      QMenu* menu=qobject_cast<QMenu*>(parent);
                      QString title=menu->title();
                  

                  and here is the error :

                  /mnt/A_BT_DEC10/BT__PROGRAMS/A_JAN11/A_BT_LIBRARY/terminal_Bluetooth/mainwindow_Bluetooth_copy.cpp:42: error: C++ requires a type specifier for all declarations
                  mainwindow_Bluetooth_copy.cpp:42:10: error: C++ requires a type specifier for all declarations
                  QObject::connect(&MainWindow_Bluetooth::subMenu,&QMenu::triggered,&MainWindow_Bluetooth::subMenu,[](QAction* action)
                           ^
                  

                  It is not clear where "^" is pointing...

                  UPDATE
                  when "connect" is on A SINGLE line the "^" points to "action".

                  M 1 Reply Last reply
                  0
                  • A Anonymous_Banned275

                    @mpergand I am trying to modify your code and having issues. Could use some help to resolve this.

                    Here is my code snippet :

                    // modify for sumMenu
                    //subMenu[index] = subMenu[index]
                    //        ->addMenu(list[index] + " # " + QString::number(index));
                    
                    QObject::connect(&MainWindow_Bluetooth::subMenu,&QMenu::triggered,&MainWindow_Bluetooth::subMenu,[](QAction* action)
                    {// lambda
                        QString path=action->text();
                    
                    QWidget* parent=action->parentWidget();
                    path+=QString("(%1)").arg(parent->actions().indexOf(action));
                    
                    while(parent)
                        {
                        QMenu* menu=qobject_cast<QMenu*>(parent);
                        QString title=menu->title();
                    

                    and here is the error :

                    /mnt/A_BT_DEC10/BT__PROGRAMS/A_JAN11/A_BT_LIBRARY/terminal_Bluetooth/mainwindow_Bluetooth_copy.cpp:42: error: C++ requires a type specifier for all declarations
                    mainwindow_Bluetooth_copy.cpp:42:10: error: C++ requires a type specifier for all declarations
                    QObject::connect(&MainWindow_Bluetooth::subMenu,&QMenu::triggered,&MainWindow_Bluetooth::subMenu,[](QAction* action)
                             ^
                    

                    It is not clear where "^" is pointing...

                    UPDATE
                    when "connect" is on A SINGLE line the "^" points to "action".

                    M Offline
                    M Offline
                    mpergand
                    wrote on last edited by mpergand
                    #9

                    @AnneRanch said in Adapting QStringList to "two level" array:

                    I am trying to modify your code

                    This code is someway a proof of concept, I don't see any real situation to use it :)

                    Anyway, if I understand you correctly (not quite easy), you seem to need to pass some parameters for each action of your menus.
                    One way to do this is to create some dynamic variables in the action itself.
                    (in fact here I simply use setData )

                    Here an example where I set the variables with the index of the item in its menu, but it can be any values you like/need.

                    // items counts
                    int mainMenuItems=4;
                    int subMenuItems=3;
                    int subsubMenuItems=2;
                    typedef QList<int> IntList;	// for convenient
                    
                    QMenu* mainMenu=new QMenu("mainMenu");
                    for (int i=0; i<mainMenuItems; i++)
                    	{
                    	QAction* action=mainMenu->addAction(QString("item %1").arg(i));
                    	action->setData(QVariant::fromValue(IntList()<<i));
                    	}
                    
                    QMenu* subMenu=mainMenu->addMenu("sub Menu");
                    for (int i=0; i<subMenuItems; i++)
                    	{
                    	QAction* action=subMenu->addAction(QString("sub item %1").arg(i));
                    	action->setData(QVariant::fromValue(QList<int>()<<i<<mainMenuItems));
                    	}
                    
                    QMenu* subsubMenu=subMenu->addMenu("subsub Menu");
                    for (int i=0; i<subsubMenuItems; i++)
                    	{
                    	QAction* action=subsubMenu->addAction(QString("subsub item %1").arg(i));
                    	action->setData(QVariant::fromValue(QList<int>()<<i<<subMenuItems<<mainMenuItems));
                    	}
                    
                    QObject::connect(mainMenu,&QMenu::triggered,mainMenu,[](QAction* action)
                    {
                    	IntList l=action->data().value<IntList>();
                    	qDebug()<<action->text()<<l;
                    });
                    

                    logs:
                    "item 1" (1) // click on item1 in main menu
                    "sub item 2" (2, 4) // click on sub item2 (index 2) in submenu (index 4)
                    "subsub item 0" (0, 3, 4) // click in subsub item0 in subsubmenu (index 3) in submenu (index 4)

                    A 1 Reply Last reply
                    0
                    • M mpergand

                      @AnneRanch said in Adapting QStringList to "two level" array:

                      I am trying to modify your code

                      This code is someway a proof of concept, I don't see any real situation to use it :)

                      Anyway, if I understand you correctly (not quite easy), you seem to need to pass some parameters for each action of your menus.
                      One way to do this is to create some dynamic variables in the action itself.
                      (in fact here I simply use setData )

                      Here an example where I set the variables with the index of the item in its menu, but it can be any values you like/need.

                      // items counts
                      int mainMenuItems=4;
                      int subMenuItems=3;
                      int subsubMenuItems=2;
                      typedef QList<int> IntList;	// for convenient
                      
                      QMenu* mainMenu=new QMenu("mainMenu");
                      for (int i=0; i<mainMenuItems; i++)
                      	{
                      	QAction* action=mainMenu->addAction(QString("item %1").arg(i));
                      	action->setData(QVariant::fromValue(IntList()<<i));
                      	}
                      
                      QMenu* subMenu=mainMenu->addMenu("sub Menu");
                      for (int i=0; i<subMenuItems; i++)
                      	{
                      	QAction* action=subMenu->addAction(QString("sub item %1").arg(i));
                      	action->setData(QVariant::fromValue(QList<int>()<<i<<mainMenuItems));
                      	}
                      
                      QMenu* subsubMenu=subMenu->addMenu("subsub Menu");
                      for (int i=0; i<subsubMenuItems; i++)
                      	{
                      	QAction* action=subsubMenu->addAction(QString("subsub item %1").arg(i));
                      	action->setData(QVariant::fromValue(QList<int>()<<i<<subMenuItems<<mainMenuItems));
                      	}
                      
                      QObject::connect(mainMenu,&QMenu::triggered,mainMenu,[](QAction* action)
                      {
                      	IntList l=action->data().value<IntList>();
                      	qDebug()<<action->text()<<l;
                      });
                      

                      logs:
                      "item 1" (1) // click on item1 in main menu
                      "sub item 2" (2, 4) // click on sub item2 (index 2) in submenu (index 4)
                      "subsub item 0" (0, 3, 4) // click in subsub item0 in subsubmenu (index 3) in submenu (index 4)

                      A Offline
                      A Offline
                      Anonymous_Banned275
                      wrote on last edited by
                      #10

                      @mpergand Thanks for the reply. I have taken the liberty to modify your code as far as using "connect" and lambda. It is doing a good job for my purpose.
                      There is an issue with using correct "connect" sender and trigger... and I am working on that.
                      ( I did post a request for C++ code help here ... sorry OF does not member the post title....)

                      Anyway - you deserve credit for your code
                      appreciate it very much
                      ,

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved