Combo Boxes in Item Views

Sample code to use combo boxes as editor widgets in an item view or item widget.

The delegate creates a combo box if the index is in the second column of a list view. For the other columns it just returns the default editor, that QStyledItemDelegate [doc.qt.nokia.com] creates.

File itemdelegate.h

  1. // ----- File itemdelegate.h -----
  2. #ifndef ITEMDELEGATE_H
  3. #define ITEMDELEGATE_H
  4.  
  5. #include <QStyledItemDelegate>
  6.  
  7. class ComboBoxItemDelegate : public QStyledItemDelegate
  8. {
  9.     Q_OBJECT
  10.  
  11. public:
  12.     ComboBoxItemDelegate(QObject *parent = 0);
  13.     ~ComboBoxItemDelegate();
  14.  
  15.     virtual QWidget *createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const;
  16.     virtual void setEditorData ( QWidget *editor, const QModelIndex &index ) const;
  17.     virtual void setModelData ( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const;
  18.  
  19. };
  20.  
  21. #endif // ITEMDELEGATE_H

File itemdelegate.cpp

  1. // ----- File itemdelegate.cpp -----
  2. #include "itemdelegate.h"
  3. #include <QComboBox>
  4.  
  5. ComboBoxItemDelegate::ComboBoxItemDelegate(QObject *parent)
  6.     : QStyledItemDelegate(parent)
  7. {
  8. }
  9.  
  10.  
  11. ComboBoxItemDelegate::~ComboBoxItemDelegate()
  12. {
  13. }
  14.  
  15.  
  16. QWidget* ComboBoxItemDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const
  17. {
  18.     // ComboBox ony in column 2
  19.     if(index.column() != 1)
  20.         return QStyledItemDelegate::createEditor(parent, option, index);
  21.  
  22.     // Create the combobox and populate it
  23.     QComboBox *cb = new QComboBox(parent);
  24.     int row = index.row();
  25.     cb->addItem(QString("one in row %1").arg(row));
  26.     cb->addItem(QString("two in row %1").arg(row));
  27.     cb->addItem(QString("three in row %1").arg(row));
  28.     return cb;
  29. }
  30.  
  31.  
  32. void ComboBoxItemDelegate::setEditorData ( QWidget *editor, const QModelIndex &index ) const
  33. {
  34.     if(QComboBox *cb = qobject_cast<QComboBox *>(editor)) {
  35.         // get the index of the text in the combobox that matches the current value of the itenm
  36.         QString currentText = index.data(Qt::EditRole).toString();
  37.         int cbIndex = cb->findText(currentText);
  38.         // if it is valid, adjust the combobox
  39.         if(cbIndex >= 0)
  40.             cb->setCurrentIndex(cbIndex);
  41.     } else {
  42.         QStyledItemDelegate::setEditorData(editor, index);
  43.     }
  44. }
  45.  
  46.  
  47. void ComboBoxItemDelegate::setModelData ( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
  48. {
  49.     if(QComboBox *cb = qobject_cast<QComboBox *>(editor))
  50.         // save the current text of the combo box as the current value of the item
  51.         model->setData(index, cb->currentText(), Qt::EditRole);
  52.     else
  53.         QStyledItemDelegate::setModelData(editor, model, index);
  54. }

File main.cpp

  1. // ----- File main.cpp -----
  2. #include <QApplication>
  3. #include <QTableWidget>
  4.  
  5. #include "itemdelegate.h"
  6.  
  7. int main(int argc, char *argv[])
  8. {
  9.     QApplication a(argc, argv);
  10.     QTableWidget tw;
  11.  
  12.     ComboBoxItemDelegate *cbid = new ComboBoxItemDelegate(&tw);
  13.     tw.setItemDelegate(cbid);
  14.     tw.setColumnCount(4);
  15.     tw.setRowCount(10);
  16.     tw.resize(600,400);
  17.     tw.show();
  18.  
  19.     return a.exec();
  20. }

Categories: