Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [SOLVED] QStyledItemDelegate where to tweak QVariants?
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] QStyledItemDelegate where to tweak QVariants?

Scheduled Pinned Locked Moved General and Desktop
12 Posts 3 Posters 5.0k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • I Offline
    I Offline
    i92guboj
    wrote on last edited by
    #1

    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 Reply Last reply
    0
    • S Offline
      S Offline
      Santosh Reddy
      wrote on last edited by
      #2

      @index.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?

      SS

      1 Reply Last reply
      0
      • I Offline
        I Offline
        i92guboj
        wrote on last edited by
        #3

        [quote author="Santosh Reddy" date="1377612617"]@index.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 :)

        1 Reply Last reply
        0
        • S Offline
          S Offline
          Santosh Reddy
          wrote on last edited by
          #4

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

          };@

          SS

          1 Reply Last reply
          0
          • I Offline
            I Offline
            i92guboj
            wrote on last edited by
            #5

            [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 :)

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              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.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • I Offline
                I Offline
                i92guboj
                wrote on last edited by
                #7

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

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  Then you can subclass QSortFilterProxyModel and use that one in place

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • S Offline
                    S Offline
                    Santosh Reddy
                    wrote on last edited by
                    #9

                    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

                    SS

                    1 Reply Last reply
                    0
                    • I Offline
                      I Offline
                      i92guboj
                      wrote on last edited by
                      #10

                      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...

                      1 Reply Last reply
                      0
                      • I Offline
                        I Offline
                        i92guboj
                        wrote on last edited by
                        #11

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

                        1 Reply Last reply
                        0
                        • I Offline
                          I Offline
                          i92guboj
                          wrote on last edited by
                          #12

                          [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. ;)

                          1 Reply Last reply
                          0

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved