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. Format percentage column
QtWS25 Last Chance

Format percentage column

Scheduled Pinned Locked Moved General and Desktop
10 Posts 3 Posters 8.3k Views
  • 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.
  • A Offline
    A Offline
    abibiano
    wrote on last edited by
    #1

    I have a decimal database column that stores percentages values, for example 0.05 is 5% and 0.2 = 20%.

    I have a custom model inherited from QSQLTableModel for this table and want to modify it to display 20% on all QlineEdits I use on my views instead of 0.2

    How can I do it?

    I have already overridden the data function on my custom model to display it correctly on a QTreeView, but it doesn’t work for QlineEdits:

    @QVariant ModelCustomers::data(const QModelIndex &index, int role) const
    {
    if(!index.isValid())
    return QVariant();

    QVariant value = ModelBase::data(index, role);
    
    if (index.column() == CUSTOMERS_DISCOUNT)
    {
        if (role == Qt::TextAlignmentRole)
            return Qt::AlignRight;
        else if (role == Qt::DisplayRole)
            value = QString("%1\%").arg(value.toString());
    }
    return value;
    

    }@

    1 Reply Last reply
    0
    • A Offline
      A Offline
      andre
      wrote on last edited by
      #2

      You probably want to also return your value string for the Qt::EditDataRole.

      1 Reply Last reply
      0
      • B Offline
        B Offline
        broadpeak
        wrote on last edited by
        #3

        The "return value;" is in right place?

        Probably this is better:
        @
        if (index.column() == CUSTOMERS_DISCOUNT)
        {
        if (role == Qt::TextAlignmentRole)
        return Qt::AlignRight;
        else if (role == Qt::DisplayRole)
        // here return with good data!
        return value = QString("%1%").arg(value.toString());
        }
        return QVariant(); // if you have invalid data, you have to return an "empty" QVariant
        @

        1 Reply Last reply
        0
        • A Offline
          A Offline
          andre
          wrote on last edited by
          #4

          @broadpeak:
          I think the code abibiano posted is correct in this sense. He first retreives the value the baseclass returns (which might be an invalid QVariant) and only then checks if the role & column match the ones he is interested in. You are right in general, but in this case, it is handled by the base class.

          1 Reply Last reply
          0
          • B Offline
            B Offline
            broadpeak
            wrote on last edited by
            #5

            @Andre
            Ahhh, yes, you are right!
            But, if abibiano doesn't want to modify the "percent", it would be much better solution, that he in the SQL query can "translate" the float to percent (means: using "as" and some computation in SQL). But, if he want to modify the percent, he has to use delegate (createeditor() family) for the app.
            I think. Hm, in theory, the first snippet shoulda work :S

            1 Reply Last reply
            0
            • A Offline
              A Offline
              abibiano
              wrote on last edited by
              #6

              Thanks for replay, as you can suppose I’m newbie on QT

              If it is easier to implement, I can store in the DB the value as percent (instead of 0.1 as 10), but I continue with the problem to display the % sign after the value on edit fields.

              Can you give some example how to implement the Qt::EditDataRole to display also the % sign on edit?

              Is it also necessary to implement setData to store the value on the DB without percent sign?

              A lot of thanks,

              Alex B.

              1 Reply Last reply
              0
              • A Offline
                A Offline
                andre
                wrote on last edited by
                #7

                You do that in exactly the same way as you do in lines 12-13 of your fist snippet, only you change the data role. You also need to reimplement setData, of course. I would make it accept the value with our without percent sign at the end.

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  abibiano
                  wrote on last edited by
                  #8

                  A never implemented the setData before. Can you give me some example. I think it has to be somethink like this:

                  @bool ModelCustomers::setData(const QModelIndex &index, const QVariant &value, int role) {
                  if(!index.isValid())
                  return false;

                  if (index.column() == CUSTOMERS_DISCOUNT)
                  {
                      QVariant data = value <-- I dont' know waht to put here
                      return ModelBase::setData(index, data, Qt::EditRole);
                  }
                  else
                      return ModelBase::setData(index,value,role);
                  

                  }@

                  but I'm to sure how to parse the imput string

                  Alex B.

                  1 Reply Last reply
                  0
                  • A Offline
                    A Offline
                    andre
                    wrote on last edited by
                    #9

                    That is basic string parsing. You could something like this (untested):
                    @
                    QString valueString = value.toString();
                    //trim off white space
                    valueString = valueString.trimmed(); //get rid of additional white space
                    if (valueString.endsWith('%'))
                    valueString.chop(1); //chop off % sign if we have one
                    bool ok;
                    double valueDbl = valueString.toDouble(&ok);
                    if (!ok)
                    return false; //value is not a number
                    //if you mapped 0.2 to 20%, then you have to map the other way too:
                    valueDbl /= 100.0;

                    //set the value on the actual data store and return true
                    @

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      abibiano
                      wrote on last edited by
                      #10

                      A lot of thanks, now I understand how it works!

                      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