[Qt-interest] properly subclassing QAbstractItemDelegate

Neil Girdhar mistersheik at gmail.com
Tue May 12 18:04:28 CEST 2009


Hi all,

I am trying to follow the model/view/controller paradigm. I am pretty sure
that my model and view are right, but I think I'm doing some things wrong in
my delegate. Everything "works", except the first click to a control just
"lights up the control" and the second one interacts with it. Is this how
delegates are usually implemented? My implementation requires a lot of
construction and destruction (hidden by scoped_ptr) so any tips on that are
also helpful.

Thanks in advance!

QWidget *ParmDelegate::createWidget(const QModelIndex &index) const {
    if (!index.isValid())
        return NULL;
    const Parm  *p = static_cast<const Parm*>(index.internalPointer());
    QWidget *w = p->createControl();
    w->setAutoFillBackground(true);
    w->setBackgroundRole(QPalette::Base);  // white background instead of
grey
    return w;
}

QWidget*
ParmDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem
&option, const QModelIndex &index) const {
    QWidget *retval = createWidget(index);
    if (dynamic_cast<QComboBox*>(retval))
        connect(retval, SIGNAL(activated(int)), this,
SLOT(commitAndCloseEditor()));
    else if (dynamic_cast<QSlider*>(retval))
        connect(retval, SIGNAL(sliderReleased()), this,
SLOT(commitAndCloseEditor()));
    else if (dynamic_cast<QAbstractButton*>(retval))
        connect(retval, SIGNAL(clicked()), this,
SLOT(commitAndCloseEditor()));
    else
        connect(retval, SIGNAL(editingFinished()), this,
SLOT(commitAndCloseEditor()));
    retval->setFocusPolicy(Qt::StrongFocus);
    retval->setParent(parent);
    return retval;
}

void
ParmDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    const Parm  *p = static_cast<const Parm*>(index.internalPointer());
    p->setEditorData(editor);
}

void
ParmDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const
QModelIndex &index) const {
    ParmControl::Base*  base = dynamic_cast<ParmControl::Base*>(editor);
    model->setData(index, base->toQVariant());
}

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

void
ParmDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const {
    scoped_ptr<QWidget> w(createWidget(index));
    if (!w)
        return;
    const Parm  *p = static_cast<const Parm*>(index.internalPointer());
    setEditorData(w.get(), index);
    w->setGeometry(option.rect);
    w->render(painter, option.rect.topLeft());
}

QSize
ParmDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex
&index) const {
    scoped_ptr<QWidget> w(createWidget(index));
    if (!w)
        return QSize(0,0);
    return w->sizeHint();
}

bool
ParmDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const
QStyleOptionViewItem &option, const QModelIndex &index) {
    QMouseEvent *m_event = dynamic_cast<QMouseEvent*>(event);
    if (m_event != NULL && m_event->button() == Qt::LeftButton)
        myView->openPersistentEditor(index);
    return false;
}

void
ParmDelegate::commitAndCloseEditor() {
    QWidget *editor = static_cast<QWidget *>(sender());
    ParmControl::Base* base = dynamic_cast<ParmControl::Base*>(editor);
    emit commitData(editor);
    emit closeEditor(editor, QAbstractItemDelegate::EditNextItem);
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20090512/a34b05e5/attachment.html 


More information about the Qt-interest-old mailing list