PDA

View Full Version : Help needed with QItemDelegate



cyberboy
8th July 2008, 20:30
Hi,

I'm busy with my QItemDelegate and my custom model!
But there are a few things that I don't get quite well.

Correct me if I'm wrong!
The painter function of the QItemDelegate is invoked when the view sees the delegated cell.
The createEditor function is invoked when the user wants to edit the cell.
The setEditorData function is invoked after the widget is created.
And the setModelData is invoked when the user finished editing.

So with this knowledge in the back of my head I started coding!


#include "checkBoxDelegate.h"

#include <QtGui>

CheckBoxDelegate::CheckBoxDelegate(QObject *parent)
:QItemDelegate(parent)
{
qDebug("CheckBoxDelegate::CheckBoxDelegate(): constructing delegate");
}

void CheckBoxDelegate::paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
qDebug("CheckBoxDelegate::paint(): painting the delegate");

const QAbstractItemModel *model = index.model();

if(!model)
QItemDelegate::paint(painter, option, index);

if(index.data() == 2)
{
painter->fillRect(option.rect, QBrush(QColor("green")));
}else{
painter->fillRect(option.rect, QBrush(QColor("red")));

}

}


QWidget *CheckBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option , const QModelIndex &index) const
{
qDebug("CheckBoxDelegate::createEditor(): create checkbox");
const QAbstractItemModel *model = index.model();

if(!model)
QItemDelegate::createEditor(parent, option, index);

QCheckBox *checkbox = new QCheckBox(parent);
if(QVariant(model->data(index, Qt::EditRole)).toInt() == 2)
checkbox->setCheckState(Qt::Checked);
else
checkbox->setCheckState(Qt::Unchecked);

return checkbox;

}
void CheckBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
qDebug("CheckBoxDelegate::setEditorData(): set editor data");

QCheckBox *checkbox = qobject_cast<QCheckBox *>(editor);


if(!checkbox)
return QItemDelegate::setEditorData(editor, index);

const QAbstractItemModel *model = index.model();


if(QVariant(model->data(index, Qt::EditRole)).toInt() == 2)
checkbox->setCheckState(Qt::Checked);
else
checkbox->setCheckState(Qt::Unchecked);


}

void CheckBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
qDebug("CheckBoxDelegate::setModelData(): Set model data");

if(!index.isValid())
return;

return QItemDelegate::setModelData(editor, model, index);
}

The idea is to show a checkbox with a green or red background. Indicating whether it's checked or not. (It's a little bit strange but it has to be a field that catches your attention).

And the background drawing works, its green when the state is 2 and red when it's 0.
But I can't see the widget until I start editing the cell.

Is there a way that the checkbox is all ready visible before I start editing.

I have the same problem with the date delegate, it isn't visible when the table is loaded!

Greetings

Cyberboy

wysota
8th July 2008, 21:16
The editor is created only when a particular cell needs editing, so in normal conditions at most one editor per view exists. You can make a persistant editor, but doing that for more than a few items slows down the application terribly.

Now the good news - you don't need a custom delegate :) The standard delegate can draw the checkbox for you if you use the Qt::CheckStateRole and return Qt::ItemIsUserCheckable among the flags for a particular item.

cyberboy
9th July 2008, 18:18
Oke, so I have to pass a Qt::CheckStateRole in my model for the particular column/cell and the standard delegate will take care of the rest?

(There isn't a standard for a QDateEdit, is it? At least I didn't found one in the docs!)

wysota
9th July 2008, 18:21
Date time edit has to be handled using a real editor, but you can emulate its looks using a custom delegate.