Solved 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? -
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()
orcurrentData()
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.
-
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()
orcurrentData()
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?!
-
No, you can't set this up in the designer.