23 #include "multicombobox.h" 24 #include <QAbstractItemView> 25 #include <QApplication> 27 #include <QItemDelegate> 28 #include <QStylePainter> 31 class MultiComboBoxEditor :
public QCheckBox
34 MultiComboBoxEditor(QWidget *parent)
35 : QCheckBox(parent) {}
38 bool hitButton(
const QPoint &pos)
const override 44 return QAbstractButton::hitButton(pos);
50 class MultiComboBoxDelegate :
public QItemDelegate
54 MultiComboBoxDelegate(QObject *parent)
55 : QItemDelegate(parent) {}
57 void paint(QPainter *painter,
const QStyleOptionViewItem &option,
58 const QModelIndex &index)
const override 61 bool value = index.data(Qt::UserRole).toBool();
62 QString text = index.data(Qt::DisplayRole).toString();
65 const QStyle *style = QApplication::style();
66 QStyleOptionButton opt;
67 opt.state |= value ? QStyle::State_On : QStyle::State_Off;
68 opt.state |= QStyle::State_Enabled;
70 opt.rect = option.rect;
73 style->drawControl(QStyle::CE_CheckBox, &opt, painter);
76 QWidget *createEditor(QWidget *parent,
77 const QStyleOptionViewItem &option,
78 const QModelIndex &index )
const override 82 return new MultiComboBoxEditor(parent);
85 void setEditorData(QWidget *editor, const QModelIndex &index)
const override 87 auto myEditor =
static_cast<QCheckBox *
>(editor);
88 myEditor->setText(index.data(Qt::DisplayRole).toString());
89 myEditor->setChecked(index.data(Qt::UserRole).toBool());
92 void setModelData(QWidget *editor, QAbstractItemModel *model,
93 const QModelIndex &index)
const override 96 auto myEditor =
static_cast<QCheckBox *
>(editor);
97 bool value = myEditor->isChecked();
101 QMap<int, QVariant> data;
102 data.insert(Qt::DisplayRole, myEditor->text());
103 data.insert(Qt::UserRole, value);
104 model->setItemData(index, data);
107 void updateEditorGeometry(QWidget *editor,
108 const QStyleOptionViewItem &option,
const QModelIndex &index )
const override 111 editor->setGeometry(option.rect);
117 MultiComboBox::MultiComboBox(QWidget *widget )
120 view()->setItemDelegate(
new MultiComboBoxDelegate(
this));
122 view()->setEditTriggers(QAbstractItemView::CurrentChanged);
123 view()->viewport()->installEventFilter(
this);
124 view()->setAlternatingRowColors(
true);
128 MultiComboBox::~MultiComboBox()
132 QString MultiComboBox::displayText()
const 134 return selectedItemTexts().join(
", ");
137 bool MultiComboBox::eventFilter(QObject *
object, QEvent *event)
139 if (
object == view()->viewport())
141 if (handleViewViewportEvent(event))
144 return QComboBox::eventFilter(
object, event);
147 bool MultiComboBox::handleViewViewportEvent(QEvent *event)
149 switch (event->type())
166 view()->edit(model()->index(0, 0));
170 case QEvent::MouseButtonRelease:
179 void MultiComboBox::paintEvent(QPaintEvent *)
181 QStylePainter painter(
this);
182 painter.setPen(palette().color(QPalette::Text));
185 QStyleOptionComboBox opt;
186 initStyleOption(&opt);
189 opt.currentText = displayText();
190 painter.drawComplexControl(QStyle::CC_ComboBox, opt);
191 painter.drawControl(QStyle::CE_ComboBoxLabel, opt);
194 QStringList MultiComboBox::selectedItemTexts()
const 197 for (
int i = 0; i < count(); ++i)
199 bool checked = itemData(i).toBool();
201 result << itemText(i);
206 void MultiComboBox::setSelectedTexts(
const QStringList &texts)
208 for (
int i = 0; i < count(); ++i)
209 setItemData(i, static_cast<bool>(texts.contains(itemText(i))));