[SOLVED] QStyledItemDelegate where to tweak QVariants?



  • Hello.

    I am using a derivative of this class to tweak a bit the info I am going to present in my QTableView.

    So far, I have reimplemented the three mandatory methods, plus the paint() method. Up to now, I have been using paint() to change the colors of the QTableView rows, depending on their contents.

    But I'd also like to display some cells in a certain way, without modifying the database nor the data model.

    I am trying to use index.model()->setData() from the paint() method, but I am having no luck so far, 'cause this:

    [code]
    void CompletionDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
    ...
    if(index.column() == 5)
    {
    QVariant var;
    var = index.data();
    var = var.toString().append(QChar(8364));
    index.model()->setData(index, var);
    qDebug() << Q_FUNC_INFO << QString("the variant now holds %1").arg(var.toString());
    }
    ...
    }
    [/code]

    leads to this:

    [code]
    /home/i92guboj/clientes/rafacarrasco/kooker/completiondelegate.cpp:116: error: passing 'const QAbstractItemModel' as 'this' argument of 'virtual bool QAbstractItemModel::setData(const QModelIndex&, const QVariant&, int)' discards qualifiers [-fpermissive]
    [/code]

    I've also tried to use the displayText() method, but then I can't discriminate between columns. At least, I don't know how...

    What am I doing wrong?

    Thank you for your help :)



  • 1.model()->setData(index, var);@

    This line is not allowled because it is trying to modify the value returned by model(). Value returned by the model() is also a const variable. In C/C++ modifying const variable is not allowled by compiler.

    Why do you need that line?



  • [quote author="Santosh Reddy" date="1377612617"]2.model()->setData(index, var);@

    This line is not allowled because it is trying to modify the value returned by model(). Value returned by the model() is also a const variable. In C/C++ modifying const variable is not allowled by compiler.

    Why do you need that line?[/quote]

    I guess my question is as poorly worded as always hehe.

    I understand the error, in which regards the C++ side of things.

    What I truly meant to ask is, what the correct method would be to change how a given cell is displayed.

    As you can infer from the code above, I am trying to change how a given column in a QTableView is displayed, by using a QStyledItemDelegate.

    Column 5 holds prices, so, what I want to do is to append the Euro sign to every value if index.column() == 5.

    I think that the model.setData() method is not the correct way to do it, because (if that would be possible at all), it would change the data in the model, which is not what I want (I just want to change how it's displayed).

    But I don't even know if QStyledItemDelegate::paint() is the correct location to do this either. So I am at a complete loss.

    I have managed to display some text there by using painter.drawText(), but that doesn't change the original text, and they both display alongside each other.

    I hope I've cleared myself up a bit :)



  • bq. Column 5 holds prices, so, what I want to do is to append the Euro sign to every value if index.column() == 5.

    You have use proxy model instead of item delegate.
    Use a custom QIdentityProxyModel and override the data() method of it.

    @class MyProxy : public QIdentityProxyModel
    {
    public:
    explicit MyProxy(QObject * parent) : QIdentityProxyModel(parent) { }

    QVariant MyModel::data(const QModelIndex & index, int role = Qt::DisplayRole) const
    {
        if((index.column == 5) && (role == Qt::DisplayRole))
            return QString("$ %1").arg(QIdentityProxyModel::data(index).toString());
    
        return QIdentityProxyModel::data(index, role);
    }
    

    };@



  • [quote author="Santosh Reddy" date="1377614316"]bq. Column 5 holds prices, so, what I want to do is to append the Euro sign to every value if index.column() == 5.

    You have use proxy model instead of item delegate.
    Use a custom QIdentityProxyModel and override the data() method of it.
    [/quote]

    Well, I might look into using the proxy on-top of the delegate, but not instead of it. I need the delegate to put a combobox into one of the columns, and to do some other things (colors, spinboxes, and that stuff).

    I'll report back. Still, if someone else has another idea to share I am listening.

    Thanks :)


  • Lifetime Qt Champion

    Hi,

    For things like background color, some text transformation etc... In fact, what you can translate in one of Qt's role (Display, Decoration etc...), the identity proxy model is generally the way to go.

    If you need a special editor, then the QStyledItemDelegate is needed. Try to avoid re-implementing paint if it's for things that can be done from the model side.



  • Well, the data source is a QSortFilterProxyModel, the delegate is used to provide a convenient way to input data (a combobox with a completer in one field, and some other widgets in other columns).

    As I understand it, I should be putting yet another proxy (the identity one) in the middle of the QSortFilterProxyModel and the view with its custom delegate.

    Is that right?

    Or, maybe, this could be achieved directly in the already present QSortFilterProxyModel instead of piling one more proxy on top of that?

    I will be looking into this and report back whatever I find. Still any guidance is welcome. Thank you so much for your help ;)


  • Lifetime Qt Champion

    Then you can subclass QSortFilterProxyModel and use that one in place



  • bq. Is that right?

    Yes

    bq. Or, maybe, this could be achieved directly in the already present QSortFilterProxyModel instead of piling one more proxy on top of that?

    It will be better to add one more layer of model, it will be a more flexible solution. Either ways you have to implement a custom model either based on QSortFilterProxyModel or QIdentityProxyModel



  • I am considering both ways, thank you both, your help is much appreciated.

    Regarding the data it's going smooth. Just some basic string mangling in data().

    However I still don't see how to approach the colouring and that stuff. Being a model, I assume I can't use an approach similar to the one I used in QItemDelegate::paint(), so, how does a model tells a view that it wants the text or background rendered in a given colour?

    The QIdentityModel reference says that "a proxy model could be created to define the font used, or the background colour, or the tooltip etc.", but it gives absolutely no hint on how to go about that. Only on how to manipulate data, which is something evident anyway...



  • Sorry, I just found about Qt::BackgroundRole, I think I can handle the rest. Thank you again :)



  • [quote author="SGaist" date="1377617240"]Hi,

    For things like background color, some text transformation etc... In fact, what you can translate in one of Qt's role (Display, Decoration etc...), the identity proxy model is generally the way to go.

    If you need a special editor, then the QStyledItemDelegate is needed. Try to avoid re-implementing paint if it's for things that can be done from the model side.[/quote]

    Thanks, this was really useful. I am still trying to become accustomed to all this "role" stuff. ;)


Log in to reply
 

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