PDA

View Full Version : Delegate not calling createEditor()



bmatous
16th April 2013, 10:14
I have ComboBox with checkable items made with CheckBox delegate. When this ComboBox is opened the first item's delegate's 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!

Santosh Reddy
16th April 2013, 15:45
First thing QAbstractItemView::AllEditTriggers is a strange thing, every action will start the editor, you will have problem selecting the item in the first place.


When this ComboBox is opened the first item's delegate's createEditor() is not called but when you move to second item it is called and delegate is properly created.
Try to set the current index to -1 when you start, and then try selecting the first item, and see the magic.


The problem is only with selecting first item for first time. If you have got only one item in comboBox this item is unselectable.
The problem is not with the first item, the problem is selecting (hovring) over an already selected item. Try this, set the index to 4 when you start, and move the mouse on to 4th item (note not to cross over any other items in the combo), you will need to take mouse out of the combo widget and bring it over the 4th item from outside directly.

I think this is just the begining of other host of operational problems, and I think it is contributed by improper use of QAbstractItemView::AllEditTriggers. Also I don't think you are able to see the items normaly in the combo box, I mean only the drop down will work, but after selection the item will not be displayed in the combo.

bmatous
18th April 2013, 09:42
Thank you. Your advice was helpful the problem was really with currently selected index. So when I set currentIndex to -1 before every opening of ComboBox it is working properly.

I have set AllEditTriggers because it was recommended on most of fora to do so to prevent future error. After you have advised me I have returned back to CurrentChanged which I have been using before.