QTableWidgetItem设置隐藏数据

4

在给定一个QTableWidget的情况下,是否有一种方法可以为单元格(QTableWidgetItem)设置“隐藏”值,该值与显示的值不同?

例如,我的单元格应该显示“Item 1”文本,但双击它时,编辑应仅针对值1,显示默认为1的SpinBox。

换句话说,单元格显示的文本应该是从与单元格相关联的值(隐藏)开始创建的。

我在QTableWidgetItem上找不到适当的QT函数。

1个回答

4

是的,您可以使用QTableWidgetItem::setData()函数来实现这一点。第一个参数定义了角色,第二个参数是数据本身。除了标准角色(Qt :: DisplayRole定义项目文本等)之外,您还可以使用自定义角色来存储其他数据。

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

为了检索它,您必须使用相同的角色:
QVariant v = item.data(Qt::UserRole);
int i = v.toInt();

一般来说,为了更好的代码风格,你可以使用枚举类型来定义你自己的数据:
enum {
    MyIntData = Qt::UserRole,
    MyDblData,
    MySuperItem
};

更新

下面是使用项目委托类的替代解决方案:

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);
        }
    }
};

如何创建表格小部件和项目:

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();

    [..]
}

我尝试了你的代码,使用 setText 来显示数据,使用 setData(Qt::UserRole, myData) 存储“隐藏”的值。然后,我将 cellChanged(int, int) 信号连接到一个槽上,但是双击单元格时,编辑器显示的标签是“Item 1”,而不是实际的值(1)。我错过了什么? - ABCplus
@ABCplus,请尝试使用Qt::EditRole设置自定义数据,即 setData(Qt::EditRole, myData) - vahancho
完成,但是当 setData(Qt::UserRole, myData) 设置 myData 值为隐藏时,setData(Qt::EditRole, myData) 在单元格上显示该值。 - ABCplus
当您编辑单元格时,带有Qt :: EditRole角色的数据集将可见。如果单元格不处于编辑模式,则将显示使用Qt :: DisplayRole角色设置的值。 - vahancho
我看到的是setData函数会覆盖之前的数据,这意味着如果我写了setData(Qt::EditRole, 1)然后又写了setData(Qt::DisplayRole, 2),那么单元格中显示的数据就是2,并且双击单元格时会显示一个值为2的旋转框。是否有一些额外的属性需要设置给QTableWidget? - ABCplus
@ABCplus,请查看我的更新答案。建议使用项目委托类来处理单元格编辑器的自定义数据。 - vahancho

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接