QCheckBox in QComboBox
-
Hello.
I bumped into a problem of adding an item QCheckBox into QComboBox. What Ive found is the code for creating ItemDelegate for QComboBox, but it makes all of items in QComboBox as QCheckBox. My task is to add just one check box into the list of common combobox
s items...
Here is a code I found:
@class CheckBoxList: public QComboBox
{
Q_OBJECT;public:
CheckBoxList(QWidget *widget = 0);
virtual ~CheckBoxList();
virtual void paintEvent(QPaintEvent *);
void SetDisplayText(QString text);
QString GetDisplayText() const;private:
QString m_DisplayText;
};@@class CheckBoxListDelegate : public QItemDelegate
{
public:
CheckBoxListDelegate(QObject *parent)
: QItemDelegate(parent)
{
;
}void 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;// draw item data as CheckBox
style->drawControl(QStyle::CE_CheckBox,&opt,painter);
}QWidget *createEditor(QWidget *parent,
const QStyleOptionViewItem & option ,
const QModelIndex & index ) const
{
// create check box as our editor
QCheckBox *editor = new QCheckBox(parent);
return editor;
}void setEditorData(QWidget *editor,
const QModelIndex &index) const
{
//set editor data
QCheckBox myEditor = static_cast<QCheckBox>(editor);
myEditor->setText(index.data(Qt::DisplayRole).toString());
myEditor->setChecked(index.data(Qt::UserRole).toBool());
}void 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);
}
};CheckBoxList::CheckBoxList(QWidget *widget )
:QComboBox(widget),m_DisplayText("")
{
// set delegate items view
view()->setItemDelegate(new CheckBoxListDelegate(this));// Enable editing on items view
view()->setEditTriggers(QAbstractItemView::CurrentChanged);
}CheckBoxList::~CheckBoxList()
{
;
}void CheckBoxList::paintEvent(QPaintEvent *)
{
QStylePainter painter(this);
painter.setPen(palette().color(QPalette::Text));// draw the combobox frame, focusrect and selected etc. QStyleOptionComboBox opt; initStyleOption(&opt);
// if no display text been set , use "..." as default
if(m_DisplayText.isNull())
opt.currentText = "...";
else
opt.currentText = m_DisplayText;
painter.drawComplexControl(QStyle::CC_ComboBox, opt);// draw the icon and text painter.drawControl(QStyle::CE_ComboBoxLabel, opt);
}
void CheckBoxList::SetDisplayText(QString text)
{
m_DisplayText = text;
}QString CheckBoxList::GetDisplayText() const
{
return m_DisplayText;
}@Is anyone have thoughts how to improve this code to get possibility for adding into QComboBox 2 types of items: QCheckBox and common QComboBox items?
Or there is some other ways to achieve such behaviour? -
you have to seperate inside the itemd elegate, which item to draw. You install it as item delegate for the whole list --> all items look the same. If you have a switch inside your delegate, you can also draw as standard items by calling the base implemenbation.
-
You
re right. And furthermore, I
ve done this.
For my task I had to put only one check box and it was supposed to be last item in the combo box.
So, now code for ItemDelegate looks like that:
@class CheckBoxListDelegate : public QItemDelegate
{
public:
CheckBoxListDelegate(QObject *parent) : QItemDelegate(parent)
{
}void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { //Get item data int row_count = index.model()->rowCount(index.parent()); if(index.row() == --row_count) { 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; // draw item data as CheckBox style->drawControl(QStyle::CE_CheckBox,&opt,painter); return; } return QItemDelegate::paint(painter,option,index); } QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem & option , const QModelIndex & index ) const { int row_count = index.model()->rowCount(index.parent()); // create check box as our editor if(index.row() == --row_count) { QCheckBox *editor = new QCheckBox(parent); return editor; } return 0; } void setEditorData(QWidget *editor, const QModelIndex &index) const { //set editor data QCheckBox *myEditor = static_cast<QCheckBox*>(editor); myEditor->setText(index.data(Qt::DisplayRole).toString()); myEditor->setChecked(index.data(Qt::UserRole).toBool()); } void 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); }
}; @