[Solved] QTableWidgetItem obtain value for table cell containing custom class instance



  • I started out with the StarDelegate Item. To simplify the code I have the following class:
    @
    class StarRating
    {
    public:
    StarRating(int starCount = 1)
    {
    myStarCount = starCount;
    }
    int starCount() const
    {
    return myStarCount;
    }
    void setStarCount(int starCount)
    {
    myStarCount = starCount;
    }
    private:
    int myStarCount;
    };
    Q_DECLARE_METATYPE(StarRating)
    #endif
    @

    And I do this:

    @
    QTableWidgetItem *item0 = new QTableWidgetItem;
    item0->setData(0, qVariantFromValue(StarRating(3)));
    @

    StarRating is the custom class used by the StarDelegate to display a number as stars, the number of which a user can edit. I connected the SIGNAL (cellChanged(int, int)) to a function using signalMapper, that part works. the problem is I can't access "the value" in the cell. For cells containing strings and ints QTableWidgetItempointer->text()->toInt(); or something like that works. How can I get the value in a cell that contains a custom like StarRating? To I use QTableWidgetItem::Data()? Do I override it somehow?



  • Hi,
    NOTE: The qVariantFromValue() function is OBSOLETE in Qt5!!
    Use the fromValue() function instead! Read the docs properly.
    Non the less, you used the Q_DECLARE_METATYPE so the StarRating is transportable via Signal/Slots. So, in the receiving slot you should be able to get the data from the QVariant via
    @T QVariant::value () const@
    So code might look like this:
    @
    StarRating (QVariant::value(QTableWidgetItemPointer);
    int MyCount (StarRating.starCount());
    @
    Not tested, but that might do the trick. What QVariant will probably do in this case is to copy the class that was send to the event queue and hold a pointer to it. The value() function then constructs a class interface via that pointer. In basic that's it.



  • You can either store raw pointers and static_cast (if you are absolutely sure that all items contain a valid StarDelegate) or qobject_cast them, or you do as suggested above, but you'll need a small fix: it's QVariant::value<StarDelegate>().



  • Thank you for your replies. I tried both approaches but none of them work so far:
    @
    QTableWidgetItem *item = new QTableWidgetItem;
    item->setData(0, QVariant::fromValue(StarRating(3)));
    qDebug() << (static_cast<StarRating>(*item)).starCount();
    @
    No matching function for call to StarRating::StarRating(QTableWidgetItem&)

    @
    qDebug() << StarRating(QVariant::value<StarRating>(*item)).starCount();
    @

    No matching function for call to QVariant::value(QTableWidgetItem&)
    @
    qDebug() << StarRating(QVariant(*item).value()).starCount();
    @
    No matching function for call to QVariant::QVariant(QTableWidgetItem&);

    I used the (*pointer), but the same occurs if I use the pointer itself.

    So far, I can put the StarRating into the QTableWidgetItem but I cannot extract the StarRating (or just the value of myStarCount) back from the QTableWidgetItem*.


  • Lifetime Qt Champion

    Hi,

    You are trying to convert a QTableWidgetItem to your StarRating class which is not possible. Your StarRating object is located in the data of the item not the item itself.

    Try that:
    @StarRating sr = qvariant_cast<StarRating>(item->data(Qt::DisplayRole));@

    Edit: corrected code



  • It worked like this (0 reprezents the corresponding user role.) :

    @
    StarRating sr = qvariant_cast<StarRating>(item->data(0));
    qDebug() << sr.starCount();
    @

    Thank you very much for your help.


  • Lifetime Qt Champion

    You're welcome !

    Indeed, it was a mental typo between QVariant and QTableWidgetItem


Log in to reply
 

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