Results 1 to 2 of 2

Thread: Joining together a QComboBox, QStringList, and enum

  1. #1
    Join Date
    Jan 2011
    Posts
    70
    Thanks
    43
    Thanked 4 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Joining together a QComboBox, QStringList, and enum

    I've done multiple searches (Google and otherwise) to see if there's an elegant Qt way to join together a QString and an enum for a QComboBox without having to manage two separate objects (a const QStringList and an enum), often defined in two separate places, and without hardcoding the link. Having not found anything, I thought I'd post something I came across today.

    This centers on QComboBox's little-discussed ability to store "UserData" fields in its associated data model. To associate the QString with an enum simply use the third field of QComboBox::insertItem.

    For example:
    Qt Code:
    1. enum Fruit
    2. {
    3. APPLE,
    4. ORANGE,
    5. TANGERINE,
    6. STARFRUIT
    7. }
    8.  
    9.  
    10. MainWindow::MainWindow(QWidget *parent) :
    11. QMainWindow(parent),
    12. ui(new Ui::MainWindow)
    13. {
    14. /* Set up the GUI */
    15. ui->setupUi(this);
    16.  
    17. /* generate the default options with associated values */
    18. myComboBox->insertItem(myComboBox->count(), "Star Fruit", STARFRUIT);
    19. myComboBox->insertItem(myComboBox->count(), "Granny Smith", APPLE);
    20. myComboBox->insertItem(myComboBox->count(), "Navel Orange", ORANGE);
    21. myComboBox->insertItem(myComboBox->count(), "Fancy Orange", TANGERINE);
    22. //etc
    23.  
    24. /* add another few */
    25. int nextCode = 84;
    26. myComboBox->insertItem(myComboBox->count(), "user-entered text", nextCode++);
    27. myComboBox->insertItem(myComboBox->count(), "more text", nextCode++);
    28. myComboBox->insertItem(0, "at the beginning", nextCode++);
    29. }
    30.  
    31. /* data retrieval */
    32. int MainWindow::getCode(QString label)
    33. {
    34. return myComboBox->findText(label)->toInt();
    35. }
    36. QString MainWindow::getLabel(int code = APPLE)
    37. {
    38. return myComboBox->itemText(myComboBox->findData(code)->toInt());
    39. }
    To copy to clipboard, switch view to plain text mode 

    Note that a big advantage here is that order suddenly doesn't matter any more since the "code" has been divorced from the QComboBox::currentIndex, allowing you to sort the QComboBox by code or by label, to insert at arbitrary locations (perhaps with user-entered data), and to still switch-case using the enum without error-prone hard-coding of fixed values. Plus, you only have to enter the strings once, in a single location, significantly reducing mistakes whenever you need to change the label of a particular item.

    Re-use is a piece of cake, too. If you use the same list frequently, you can easily sub-class QComboBox and insert the list into the constructor:
    Qt Code:
    1. class FruitComboBox : public QComboBox
    2. {
    3. Q_OBJECT
    4. public:
    5. explicit ClassComboBox(QWidget *parent = 0);
    6. QStringList fruitList() const;
    7. int currentFruit() const;
    8.  
    9. enum Fruits
    10. {
    11. APPLE,
    12. PEAR,
    13. ORANGE
    14. };
    15. signals:
    16. void currentFruitChanged(QString);
    17. void currentFruitChanged(int);
    18. public slots:
    19. void insertFruit(const QString& newlabel);
    20. void setCurrentFruit(const QString& fruit);
    21. void setCurrentFruit(int fruitcode);
    22. protected:
    23. int m_nextFruitCode;
    24. }
    25.  
    26. FruitComboBox::FruitComboBox(QWidget *parent) :
    27. QComboBox(parent), m_nextFruitCode(-1)
    28. {
    29. /* generate the default list */
    30. insertItem(count(), "I love apples!", APPLE);
    31. insertItem(count(), "I love pears!", PEAR);
    32. insertItem(count(), "ZOMG oranges!", ORANGE);
    33. }
    34.  
    35. void FruitComboBox::insertFruit(const QString& newlabel)
    36. {
    37. insertItem(0, newlabel, m_nextFruitCode--);
    38. }
    To copy to clipboard, switch view to plain text mode 

    Personally, I like to decrement the "nextCode" field so that it's easy to tell the difference between the enum values (>= 0) and the user-entered fields (<0).

    Hope that helps the next person trying to do something like this. Comments?


    PS—I've accomplished similar functionality using a QMap<QString, int> of label-enum pairs and then using QMap::keys() to populate the QComboBox, but the proposed method is more flexible.

  2. The following 3 users say thank you to Phlucious for this useful post:

    Big_Stone88 (27th January 2017), juannm (29th October 2013), Spitfire (25th May 2012)

  3. #2
    Join Date
    Sep 2011
    Location
    Manchester
    Posts
    538
    Thanks
    3
    Thanked 106 Times in 103 Posts
    Qt products
    Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Joining together a QComboBox, QStringList, and enum

    I was using that approach for quite some time, but it never occured to me that it's may not be that common knowledge.
    Thanks for taking the effort to post it

Similar Threads

  1. QComboBox addItems() inserts QStringList twice
    By jshafferman in forum Qt Programming
    Replies: 1
    Last Post: 3rd January 2012, 17:53
  2. Add separator to QComboBox using QStringList entries
    By mrknight in forum Qt Programming
    Replies: 3
    Last Post: 27th November 2010, 00:31
  3. Replies: 1
    Last Post: 20th October 2010, 07:19
  4. Joining tables into QTableView
    By SykeS in forum Qt Programming
    Replies: 10
    Last Post: 8th June 2010, 11:39
  5. Replies: 7
    Last Post: 2nd June 2006, 13:48

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.