Results 1 to 2 of 2

Thread: Joining together a QComboBox, QStringList, and enum

Threaded View

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

    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)

Similar Threads

  1. QComboBox addItems() inserts QStringList twice
    By jshafferman in forum Qt Programming
    Replies: 1
    Last Post: 3rd January 2012, 16:53
  2. Add separator to QComboBox using QStringList entries
    By mrknight in forum Qt Programming
    Replies: 3
    Last Post: 26th November 2010, 23:31
  3. Joining tables into QTableView
    By SykeS in forum Qt Programming
    Replies: 10
    Last Post: 8th June 2010, 10:39
  4. Replies: 7
    Last Post: 2nd June 2006, 12: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
  •  
Qt is a trademark of The Qt Company.