views:

478

answers:

2

I'm subclassing QAbstractItemDelegate. This is my code. Suggestions are welcome:

QWidget *ParmDelegate::createWidget(Parm *p, const QModelIndex &index) const {
    QWidget *w;
    if (index.column() == 0) {
     w = new QLabel(p->getName().c_str());
    } else {
     if (p->isSection())
      return NULL;
     w = p->createControl();
    }
    return w;
}

QWidget *ParmDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const {
    cout << "createEditor called" << endl;
    Parm *p = reinterpret_cast<Parm*>(index.internalPointer());
    QWidget *retval = createWidget(p, index);
    retval->setFocusPolicy(Qt::StrongFocus);
    retval->setParent(parent);
    return retval;
}

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

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

QSize ParmDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const {
    Parm *p = reinterpret_cast<Parm*>(index.internalPointer());
    scoped_ptr<QWidget> w(createWidget(p, index));
    if (!w)
     return QSize(0,0);
    return w->sizeHint();
}

bool ParmDelegate::editorEvent(QEvent * event, QAbstractItemModel * model, const QStyleOptionViewItem & option, const QModelIndex & index ) {
    cout << "editorEvent called" << endl;
    return false;
}

When this is run, I only see that editorEvent gets called twice for every edit event -- no createEditor!

A: 

I had implemented a TableView which i had inhertied from QItemDelegate. Then i had similar problem. I tracked it down to not calling 'return QItemDelegate::editorEvent(event, model, option, index);' in the editorEvent(...) method.

You can try this. Maybe it helps.

Abhay
Thanks for the reply. Unfortunately, it didn't help.FYI, I'm subclassing QAbstractItemDelegate, not QItemDelegate...
Neil G
+3  A: 

From Qt's AbstractItemDelegate documentation:

To provide custom editing, there are two approaches that can be used. The first approach is to create an editor widget and display it directly on top of the item. To do this you must reimplement createEditor() to provide an editor widget, setEditorData() to populate the editor with the data from the model, and setModelData() so that the delegate can update the model with data from the editor.

The second approach is to handle user events directly by reimplementing editorEvent().

This appears to say that you are missing something to trigger the first approach. My guess is that your model's data() function isn't returning the proper value for the Qt::EditRole option.

Caleb Huitt - cjhuitt
You led me to it, thanks! I was not setting the Qt::ItemIsEditable in the model's flags.
Neil G