2
votes

Given a QTableWidget, is there a way to set an "hidden" value for a cell (QTableWidgetItem), different from the displayed value?

For example, my cell should show "Item 1" text, but double clicking on it the editing should be only on the value 1, showing a spinbox defaulted to 1. In other words, the text showed by the cell should be created started from a value (hidden) associated with the cell.

I cannot find the proper QT function on QTableWidgetItem.

1

1 Answers

2
votes

Yes, you can do that with using QTableWidgetItem::setData() function. The first argument defines the role and second one is the data itself. Besides of the standard roles (Qt::DisplayRole that defines the item text, etc.) you can use your custom roles to store additional data. F

QTableWidgetItem item;
// Store the custom "invisible" data: 22
item.setData(Qt::UserRole, 22);

To retrieve it, you have to use the same role:

QVariant v = item.data(Qt::UserRole);
int i = v.toInt();

In general, for the sake of better code style, you can use enum to define you custom data:

enum {
    MyIntData = Qt::UserRole,
    MyDblData,
    MySuperItem
};

UPDATE

Here is the alternative solution with using item delegate class:

class Delegate : public QItemDelegate
{
public:
    void setEditorData(QWidget *editor, const QModelIndex &index) const
    {
        QVariant value = index.model()->data(index, Qt::UserRole);
        // If the editor is a spin box, set its value.
        QSpinBox *spin = qobject_cast<QSpinBox *>(editor);
        if (spin) {
            spin->setValue(value.toInt());
        } else {
            QItemDelegate::setEditorData(editor, index);
        }
    }
    void setModelData(QWidget *editor, QAbstractItemModel *model,
                        const QModelIndex &index) const
    {
        QSpinBox *spin = qobject_cast<QSpinBox *>(editor);
        if (spin) {
            int value = spin->value();
            // If the value is changed, update the data.
            if (value != index.model()->data(index, Qt::UserRole).toInt()) {
                model->setData(index, value, Qt::DisplayRole);
                model->setData(index, value, Qt::UserRole);
            }
        } else {
            QItemDelegate::setModelData(editor, model, index);
        }
    }
};

And how to create the table widget and item(s):

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QTableWidget tw(1, 1);
    tw.setItemDelegate(new Delegate);

    QTableWidgetItem *item = new QTableWidgetItem();
    item->setData(Qt::UserRole, 22);
    item->setData(Qt::DisplayRole, 33);
    tw.setItem(0, 0, item);
    tw.show();

    [..]
}