13.2.3.  Delegate Classes

[ fromfile: delegates.xml id: delegates ]

Figure 13.7.  Model, View, and Delegate

Model, View, and Delegate

Figure 13.8.  Star Delegates

Star Delegates

Example 13.5. src/modelview/playlists/stardelegate.h

#ifndef STARDELEGATE_H
#define STARDELEGATE_H

#include <QStyledItemDelegate>
#include <QStyleOptionViewItem>
class StarDelegate : public QStyledItemDelegate {
    Q_OBJECT
public:
    typedef QStyledItemDelegate SUPER;
    StarDelegate(QObject* parent=0) : SUPER(parent) {};
    QWidget* createEditor(QWidget* parent, 
                          const QStyleOptionViewItem& option,
                          const QModelIndex& index) const;
    void paint(QPainter* painter, 
               const QStyleOptionViewItem& option, 
               const QModelIndex& index) const;

    void setEditorData(QWidget* editor,
                       const QModelIndex& index) const;
    void setModelData(QWidget* editor,
                      QAbstractItemModel* model,
                      const QModelIndex& index) const;
};

#endif // STARDELEGATE_H


Example 13.6. src/modelview/playlists/stardelegate.cpp

[ . . . . ]

void StarDelegate::
    paint(QPainter* painter, 
          const QStyleOptionViewItem& option, 
          const QModelIndex& index) const {
    QString field = index.model()->headerData(index.column(),
                                           Qt::Horizontal).toString();
    if (field == "length") {
        QVariant var = index.data(Qt::DisplayRole);
        Q_ASSERT(var.canConvert(QVariant::Time));
        QTime time = var.toTime();
        QString str = time.toString("m:ss");
        painter->drawText(option.rect, str, QTextOption());
        // can't use drawDisplay with QStyledItemDelegate:
        // drawDisplay(painter, option, option.rect, str);
        return;
    }
    if (field != "rating") {
        SUPER::paint(painter, option, index);
        return;
    }
    QVariant variantData = index.data(Qt::DisplayRole);
    StarRating starRating = variantData.value<StarRating>();
    if (option.state & QStyle::State_Selected)
        painter->fillRect(option.rect, option.palette.highlight());
    starRating.paint(painter, option.rect, option.palette,
                     StarRating::ReadOnly);
}

Example 13.7. src/modelview/playlists/stardelegate.cpp

[ . . . . ]

QWidget* StarDelegate::
    createEditor(QWidget* parent, 
                 const QStyleOptionViewItem& option,
                 const QModelIndex& index) const {
    QString field = index.model()->headerData(index.column(),
                                  Qt::Horizontal).toString();
    if (field == "rating")  {
            return new StarEditor(parent);
    }
    if (field == "length") {
        return new TimeDisplay(parent);
    }
    return SUPER::createEditor(parent, option, index);
}

[Important] What Is an Edit Trigger?

There are various ways to "trigger" the View into going into edit mode. On most desktop platforms, the F2 key is a "platform edit" key. On handhelds, it may be a gesture such as double-tap, or a special button. See the API docs for setEditTriggers().

Example 13.8. src/modelview/playlists/stardelegate.cpp

[ . . . . ]

void StarDelegate::
    setEditorData(QWidget* editor, 
                  const QModelIndex& index) const {
    QVariant val = index.data(Qt::EditRole);
    StarEditor* starEditor = qobject_cast<StarEditor*>(editor);     1
    if (starEditor != 0) {
        StarRating sr = qVariantValue<StarRating>(val);             2
        starEditor->setStarRating(sr);
        return;
    }
    TimeDisplay* timeDisplay = qobject_cast<TimeDisplay*>(editor);  3
    if (timeDisplay != 0) {
        QTime t = val.toTime();
        timeDisplay->setTime(t);
        return;
    }
    SUPER::setEditorData(editor, index);                            4
    return;
}

1

Dynamic type checking.

2

Extract user type value from QVariant.

3

Dynamic type checking.

4

Let base class handle other types.


Example 13.9. src/modelview/playlists/stardelegate.cpp

[ . . . . ]

void StarDelegate::
    setModelData(QWidget* editor, QAbstractItemModel* model, 
                 const QModelIndex& index) const {
    StarEditor* starEditor = qobject_cast<StarEditor*>(editor);
    if (starEditor != 0) {
        StarRating r = starEditor->starRating();
        QVariant v;
        v.setValue<StarRating>(r);
        model->setData(index, v, Qt::EditRole);
        return;
    }
    TimeDisplay* td = qobject_cast<TimeDisplay*>(editor);
    if (td != 0) {
        QTime t = td->time();
        model->setData(index, QVariant(t));
        return;
    }
    SUPER::setModelData(editor, model, index);
    return;
}