ixM
ixM

Reputation: 1264

Using a delegate with a QDataWidgetMapper and QLabel

I'm trying to use a delegate to customize the way data from a model is displayed when using a QDataWidgetMapper.

I have two different versions of a widget, one is view-only (the data is displayed in QLabels) and the other is used to edit the data (the data is displayed in appropriate editors).

The latter one works perfectly with the delegate, everything is fine.

As you may have guessed the problem arises with the first one... When mapping the sections of my model to QLabels using the QDataWidgetMapper, the delegate is never called and the data is displayed correctly for the sections with regular data (strings, ints,...) but no data is displayed for the sections of my model with a custom data type (a kind of list) which I would like to format as a string using the delegate.

I've already performed this operation successfully when the same data is displayed in a QTableView (the method paint() of the delegate is called when the data is displayed).

After having looked at it a little bit closer, I've been able to see that, when using QLabels to display the data, the delegate is never called though I've explicitly associated a delegate to the QDataWidgetMapper using its method setItemDelegate().

So in synthesis, assume a class CustomItemDelegate which inherits QStyledItemDelegate with virtual methods:

void CustomItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {
    qDebug() << "DELEGATE: PAINT" << index.column();
    QStyledItemDelegate::paint(painter, option, index);
}

void CustomItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const {
    qDebug() << "DELEGATE: SET EDITOR DATA" << index.column();
    QStyledItemDelegate::setEditorData(editor, index);
}

and a widget with following in it:

QDataWidgetMapper* mapper = new QDataWidgetMapper();
CustomItemDelegate* delegate = new CustomItemDelegate();
mapper->setModel(model);
mapper->setItemDelegate(delegate);

mapper->addMapping(editorWidget, 1);
mapper->addMapping(label, 2, "text");

mapper->toFirst();

QTableView* view = new QTableView();
CustomItemDelegate* delegate2 = new CustomItemDelegate();
view->setModel(model);
view->setItemDelegate(delegate2);

the code outputs:

DELEGATE: SET EDITOR DATA 1
// NOTHING ?!

DELEGATE: PAINT 1
DELEGATE: PAINT 2

and as a result I got

So my questions are:

Thanks very much and I apologize in advance if the answer is obvious (but even then, thank you for pointing it out :P),

ixM

Upvotes: 2

Views: 3548

Answers (1)

O.C.
O.C.

Reputation: 6819

This is the code from QT that populates widgets

void QDataWidgetMapperPrivate::populate(WidgetMapper &m)
{
    if (m.widget.isNull())
        return;

    m.currentIndex = indexAt(m.section);
    if (m.property.isEmpty())
        delegate->setEditorData(m.widget, m.currentIndex);
    else
        m.widget->setProperty(m.property, m.currentIndex.data(Qt::EditRole));
}

In the first case when you do not specify a property delegate is used whereas in the second case the data is set to widget directly by passing your delegate.

I don't know why it was designed this way but this is how it works currently !

Upvotes: 3

Related Questions