title: Fill QMenu with an enum
body: <p>I have a few <code>struct</code>s with <code>enum</code> and <code>std::string</code> and I used to fill <code>QComboBox</code>es with them using a <code>for()</code> loop. Something like this:</p>
  
  <pre><code>struct Struct
  {
      enum Enum
      {
          ENTRY1,
          ENTRY2,
          ...
          ENTRY_ALL
      };
      std::string names[ENTRY_ALL] {...};
  };
  for(int i=0; i&lt;Struct::ENTRY_ALL; ++i)
      comboBox-&gt;insertItem(i, names[i].c_str());
  </code></pre>
  
  <p>It worked, but given recent advances I need more entries, more <code>struct</code>s, more combo boxes, and it gets ugly, so I decided I'd switch to a <code>QMenu</code>.</p>
  
  <p>Looking at the documentation and the examples, I see I have to provide a <code>connect()</code> for each entry, a <code>QAction</code> for each entry, etc, and if my <code>enum</code>s are large, this gets to be a problem, so I was wondering if there is a way to automate this process.</p>
  
  <p>My question mainly comes from how come I only need one <code>connect()</code> for each <code>QComboBox</code>  and how do <code>QComboBox</code>es know that, if I fill them up, which entry does what?</p>
  
  <hr>
  
  <p>If it helps, this is some bogus code, from here and there, of what I had:</p>
  
  <pre><code>// tank class, header:
  class Class
  {
  private:
      // main entries
      struct MainStruct
      {
          enum Enum {MAIN1, MAIN2, MAIN3, MAIN_ALL};
          std::string names[MAIN_ALL] {"Main 1", "Main 2", "Main 3"};
      };
      // secondary entries
      struct SubStruct
      {
          enum Enum {SUB1, SUB2, SUB3, SUB_ALL};
          std::string names[SUB_ALL] {"Sub 1", "Sub 2", "Sub 3"};
      };
      // family of entries for SUB2
      struct FamStruct
      {
          enum Enum {FAM1, FAM2, FAM3, FAM_ALL};
          std::string names[FAM_ALL] {"Fam 1", "Fam 2", "Fam 3"};
      }
  public:
      MainStruct mainEntries;
      SubStruct subEntries;
      FamStruct famEntries;
  };
  
  // inside the main window, there was a QComboBox doing this:
  // header
  QComboBox *cbMain, *cbSub, *cbFam;
  // source
  Class cls {Class()};
  cbMain = new QComboBox; // same for cbSub, cbFam
  // retranslateUi() (manually edited, not automatic), called each time the menu was clicked
  void MainApp::retranslateUi()
  {
      cbMain.clear();
      for(unsigned char i=0; i&lt;cls.mainEntries.MAIN_ALL; ++i)
      {
          cbMain-&gt;insertItem(i, tr(cls.mainEntries.names[i].c_str()) );
          cbMain-&gt;setItemData(i, tr(cls.mainEntries.tooltips[i].c_str()), Qt::ToolTipRole);
      }
      // same for cbSub, cbFam
  }
  // a function that did what was supposed to do when a combo box entry was clicked
  void MainApp::func() { /* execution with variables changed by the combo */ }
  /* There were additional functions taking care of the rest.
   * Whenever an entry from the combo was clicked, somehow it "knew" that the entry was
   * changed and func(), when executed, it ran with the variables changed by combo.
   */
  void MainApp::updateSub()
  {
      switch(cbMain-&gt;currentIndex())
      {
      case cls.mainEntries.MAIN1: /*subentry stuff*/ break;
      case cls.mainEntries.MAIN2: /*subentry stuff*/ break;
      case cls.mainEntries.MAIN3: /*subentry stuff*/ break;
      }
  }
  void MainApp::updateFam()
  {
      switch(cbSub-&gt;currentIndex())
      {
      case cls.subEntries.SUB1: /*fam entry stuff*/ break;
      case cls.subEntries.SUB2: /*fam entry stuff*/ break;
      case cls.subEntries.SUB3: /*fam entry stuff*/ break;
      }
  }
  /* The connect() were attached to specific combos. When an entry in cbMain was
   * clicked, cbSub and cbFam were properly updated and func() was run with
   * the proper values, when cbSub was clicked, cbFam was updated and func()
   * was run accordingly. Similar to an instant refresh.
   */
  connect(cbMain, SIGNAL(activated(int)), this, SLOT(retranslateUi()));
  connect(cbMain, SIGNAL(activated(int)), this, SLOT(updateSub()));
  connect(cbMain, SIGNAL(activated(int)), this, SLOT(func()));
  connect(cbSub, SIGNAL(activated(int)), this, SLOT(updateFam()));
  connect(cbSub, SIGNAL(activated(int)), this, SLOT(func()));
  connect(cbFam, SIGNAL(activated(int)), this, SLOT(func()));
  </code></pre>
  
  <p>Whenever I had to add new families of entries for the submenus, or even main menus with subentries, things would complicate, so I think a menu like this:</p>
  
  <pre><code>Menu:   Submenu:                AnotherSubmenu:
  menu 1  submenu 1               altsub 1
  menu 2  submenu 2 &gt; family 1    altsub 2
  menu 3  submenu 3   family 2    ...
                      family 3
  </code></pre>
  
  <p>would work better and unclutter things. The entries in <code>Menu</code> call the appropiate <code>Submenu</code>, which has its own <code>Family</code>, wherever they are, <code>Submenu</code> may call yet another level of <code>AnotherSubmenu</code>, etc.</p>