Looking for the best way to implement QSpinBox-based delegate with min/max values different for each QModelIndex



  • As for now I do it in the following way. Header file:

    @
    #include <QtWidgets/QStyledItemDelegate>

    class SpinBoxDelegate : public QStyledItemDelegate
    {
    Q_OBJECT

    public:
    explicit SpinBoxDelegate (QObject* parent = nullptr);

    virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;
    virtual void setEditorData(QWidget* editor, const QModelIndex& index) const;
    virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index);
    

    private slots:
    void onValueChanged();
    };

    @

    Source file:

    @
    #include "MyModel.h"
    #include "SpinBoxDelegate .h"
    #include <QtWidgets/QSpinBox>

    SpinBoxDelegate::SpinBoxDelegate (QObject* const parent)
    : QStyledItemDelegate(parent)
    {}

    QWidget* SpinBoxDelegate::createEditor(QWidget* const parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
    {
    Q_UNUSED(option);
    Q_UNUSED(index);
    auto* const editor = new QSpinBox(parent);
    void (QSpinBox::*spinBoxValueChanged)(int) = &QSpinBox::valueChanged;
    connect(editor, spinBoxValueChanged, this, &GSpinBoxDelegate::onValueChanged);
    return editor;
    }

    void SpinBoxDelegate::setEditorData(QWidget* const editor, const QModelIndex& index) const
    {
    auto* const spinBox = qobject_cast<QSpinBox*>(editor);
    Q_ASSUME(spinBox != nullptr);

    spinBox->setMinimum(index.model()->data(index, MyModel::MinimumRole).toInt());
    spinBox->setMaximum(index.model()->data(index, MyModel::MaximumRole).toInt());
    spinBox->setValue(index.model()->data(index, Qt::EditRole).toInt());
    

    }

    void SpinBoxDelegate::setModelData(QWidget* const editor, QAbstractItemModel* const model, const QModelIndex& index)
    {
    auto* const spinBox = qobject_cast<QSpinBox*>(editor);
    Q_ASSUME(spinBox != nullptr);

    model->setData(index, spinBox->value());
    

    }

    void SpinBoxDelegate::onValueChanged()
    {
    auto* const spinBox = qobject_cast<QSpinBox*>(sender());
    Q_ASSUME(spinBox != nullptr);

    emit commitData(spinBox);
    

    }
    @

    As you can see setEditorData() depends on the support of MinimumRole and MaximumRole by MyModel. I'd like this delegate be usable for other models in future. So, probably, it's better to define some enum directly in the delegate's class. Anyway, I have to choose some values for these roles starting from Qt::UserRole and higher, but this approach leads to a need to remember that I've reserved some values for this delegate's needs. If I want to use another custom user roles in future this situation can cause collision of roles. I'd like to avoid such restrictions.

    PS. Are those roles are general enough to be proposed as a feature request? Do they deserve being placed into the Qt::ItemDataRole enum?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.