Robust way to map QComboBox items to internal types



  • I'd like to fill a QComboBox with various types and map them to different logic in my application. What's the most robust way to do this?

    I could do string comparison:

    if(box->currentText() == "Item 1")
      do this;
    else if(box->currentText() == "Item 2")
      do that;
    

    but that breaks as soon as I rename my items and - worst of all - I might not even notice I've broken sth.

    Another solution is to do an index mapping:

    if(box->currentIndex() == 1)
      do this;
    else if(box->currentIndex() == 2)
      do that;
    

    or even

    enum ComboBoxTypes { Item_1, Item_2 }
    if(box->currentIndex() == Item)
      do this;
    else if(box->currentIndex() == Item)
      do that;
    

    but this again breaks without notice if I reorder, change or delete items.
    Is there a better way to do this?


  • Moderators

    There's setItemData() for exactly this purpose. You can associate any kind of data with the items and then add/reorder/delete them and the data stays and can be queried with itemData() or currentData()
    For example:

    enum ComboBoxTypes { Foo, Bar }
    box->setItemData(0, Foo);
    box->setItemData(1, Bar);
    
    //and then
    
    if (box->currentData().toInt() == Foo)
        //do stuff...
    

    If you need to associate more then one piece of data you can do that by specifying the extra param, e.g.

    box->setItemData(0, someStuff, Qt::UserRole);
    box->setItemData(0, someOtherStuff, Qt::UserRole + 1);
    

    and same for retrieval.

    It's also common to put a pointer to some data structure of yours as the item data. This way you get an instant access to data related to the item.



  • This is a nice solution but it only works in code, right? There is not a way to do this in QtDesigner by adding a QVariant to each item?!


  • Moderators

    No, you can't set this up in the designer.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.