November 7, 2011

abibiano abibiano
Lab Rat
7 posts

Format percentage column

 

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:

  1. QVariant ModelCustomers::data(const QModelIndex &index, int role) const
  2. {
  3.     if(!index.isValid())
  4.         return QVariant();
  5.  
  6.     QVariant value = ModelBase::data(index, role);
  7.  
  8.     if (index.column() == CUSTOMERS_DISCOUNT)
  9.     {
  10.         if (role == Qt::TextAlignmentRole)
  11.             return Qt::AlignRight;
  12.         else if (role == Qt::DisplayRole)
  13.             value = QString("%1\%").arg(value.toString());
  14.     }
  15.     return value;
  16. }

9 replies

November 7, 2011

Andre Andre
Area 51 Engineer
6031 posts

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

 Signature 

Looking for Qt developers to join our team @ i-Optics: https://qt-project.org/forums/viewthread/25393/

November 7, 2011

broadpeak broadpeak
Hobby Entomologist
360 posts

The “return value;” is in right place?

Probably this is better:

  1. if (index.column() == CUSTOMERS_DISCOUNT)
  2.     {
  3.         if (role == Qt::TextAlignmentRole)
  4.             return Qt::AlignRight;
  5.         else if (role == Qt::DisplayRole)
  6. // here return with good data!
  7.             return value = QString("%1\%").arg(value.toString());
  8.     }
  9.     return QVariant(); // if you have invalid data, you have to return an "empty" QVariant

November 7, 2011

Andre Andre
Area 51 Engineer
6031 posts

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

 Signature 

Looking for Qt developers to join our team @ i-Optics: https://qt-project.org/forums/viewthread/25393/

November 7, 2011

broadpeak broadpeak
Hobby Entomologist
360 posts

@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

November 8, 2011

abibiano abibiano
Lab Rat
7 posts

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.

November 8, 2011

Andre Andre
Area 51 Engineer
6031 posts

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.

 Signature 

Looking for Qt developers to join our team @ i-Optics: https://qt-project.org/forums/viewthread/25393/

November 8, 2011

abibiano abibiano
Lab Rat
7 posts

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

  1. bool ModelCustomers::setData(const QModelIndex &index, const QVariant &value, int role) {
  2.     if(!index.isValid())
  3.         return false;
  4.  
  5.     if (index.column() == CUSTOMERS_DISCOUNT)
  6.     {
  7.         QVariant data = value <-- I dont' know waht to put here
  8.        return ModelBase::setData(index, data, Qt::EditRole);
  9.    }
  10.    else
  11.        return ModelBase::setData(index,value,role);
  12.  
  13. }

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

Alex B.

November 8, 2011

Andre Andre
Area 51 Engineer
6031 posts

That is basic string parsing. You could something like this (untested):

  1. QString valueString = value.toString();
  2. //trim off white space
  3. valueString = valueString.trimmed(); //get rid of additional white space
  4. if (valueString.endsWith('%'))
  5.    valueString.chop(1); //chop off % sign if we have one
  6. bool ok;
  7. double valueDbl = valueString.toDouble(&ok);
  8. if (!ok)
  9.    return false; //value is not a number
  10. //if you mapped 0.2 to 20%, then you have to map the other way too:
  11. valueDbl /= 100.0;
  12.  
  13. //set the value on the actual data store and return true

 Signature 

Looking for Qt developers to join our team @ i-Optics: https://qt-project.org/forums/viewthread/25393/

November 8, 2011

abibiano abibiano
Lab Rat
7 posts

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

 
  ‹‹ Set pixels of RowWrapPolicy::WrapLongRows      QImage::save(filename) bug on windows XP platfom ››

You must log in to post a reply. Not a member yet? Register here!