1

I have ComboBox filled with CheckBoxes when the ComboBox is opened the first item's delegate createEditor is not called but when you move to second item it is called and delegate is properly created. After this when you move back to first item then delegate is working. The problem is only with selecting first item for first time. If you have got only one item in comboBox this item is unselectable.

This is my delegate's code:

#include "checkboxlistdelegate.h"

CheckBoxListDelegate::CheckBoxListDelegate(QObject *parent)
  : QItemDelegate(parent) {
}

void CheckBoxListDelegate::paint(QPainter *painter,
                                 const QStyleOptionViewItem &option,
                                 const QModelIndex &index) const {
  //Get item data
  bool value = index.data(Qt::UserRole).toBool();
  QString text = index.data(Qt::DisplayRole).toString();
  // fill style options with item data
  const QStyle *style = QApplication::style();
  QStyleOptionButton opt;
  opt.state |= value ? QStyle::State_On : QStyle::State_Off;
  opt.state |= QStyle::State_Enabled;
  opt.text = text;
  opt.rect = option.rect;
  opt.palette = QPalette(Qt::white);
  // draw item data as CheckBox
  style->drawControl(QStyle::CE_CheckBox,&opt,painter);
}

QWidget* CheckBoxListDelegate::createEditor(QWidget *parent,
                                        const QStyleOptionViewItem& option,
                                        const QModelIndex & index ) const {
  QCheckBox *editor = new QCheckBox(parent);
  editor->setStyleSheet("QCheckBox {background-color: #aaaaaa; color: white;}");
  return editor;
}

void CheckBoxListDelegate::setEditorData(QWidget *editor,
                                         const QModelIndex &index) const {
  QCheckBox *myEditor = static_cast<QCheckBox*>(editor);
  myEditor->setText(index.data(Qt::DisplayRole).toString());
  myEditor->setChecked(index.data(Qt::UserRole).toBool());
}

void CheckBoxListDelegate::setModelData(QWidget *editor,
                                        QAbstractItemModel *model,
                                        const QModelIndex &index) const {
  //get the value from the editor (CheckBox)
  QCheckBox *myEditor = static_cast<QCheckBox*>(editor);
  bool value = myEditor->isChecked();
  //set model data
  QMap<int,QVariant> data;
  data.insert(Qt::DisplayRole,myEditor->text());
  data.insert(Qt::UserRole,value);
  model->setItemData(index,data);
  emit indexChanged(index);
}

void CheckBoxListDelegate::updateEditorGeometry(QWidget *editor,
                                            const QStyleOptionViewItem &option,
                                            const QModelIndex &index ) const {
  Q_UNUSED(index);
  editor->setGeometry(option.rect);
}

And this is code of my QComboBox subclass:

CheckBoxList::CheckBoxList(QWidget *widget)
  : QComboBox(widget),title(""),selection() {
  // set delegate items view
  view()->setItemDelegate(new CheckBoxListDelegate(this));
  view()->setStyleSheet("QAbstractItemView {background-color:white;}");
  // Enable editing on items view
  view()->setEditTriggers(QAbstractItemView::AllEditTriggers);
  connect(view()->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
          this, SLOT(onItemClicked(QModelIndex)));
}

void CheckBoxList::paintEvent(QPaintEvent *) {
  QStylePainter painter(this);
  painter.setPen(palette().color(QPalette::Text));
  QStyleOptionComboBox opt;
  initStyleOption(&opt);
  opt.currentText = title;
  painter.drawComplexControl(QStyle::CC_ComboBox, opt);
  painter.drawControl(QStyle::CE_ComboBoxLabel, opt);
}

void CheckBoxList::setDisplayText(QString text) {
  title = text;
}

QString CheckBoxList::getDisplayText() const {
  return title;
}

bool CheckBoxList::isChecked(const QModelIndex& index) const {
  return view()->model()->itemData(index).value(Qt::UserRole).toBool();
}

Thank you.

0 Answers0