PDA

View Full Version : The precision range of double



nikhilqt
7th July 2009, 11:14
Hi,

I store the list of QString , and i need to populate the QStandardItemModel. Here if i put the values as QString then the 'sort' on the column occurs by string comparision, as a result my decimal numbers arrange by string comaparision and the result of the QT::Ascending or QT:: Descending turns out to be wrong.


Ex:
value1 = 2.4567
value2 = 1.34577
value3 = 10.76546
value4 = 11.45454

Result of Ascending order:
1.34577
10.76546
11.45454
2.4567, which is correct because of string compare, but numerically wrong.


Or if I put the values in Model by converting into double the range of the values are not coming properly. The 12 digit double is coming as 6 digit.



Ex:
QString value = 34.5634098790;
double nValue = value.toDouble();

//nValue = 34.5634

Can you let me know how should i maintain the precision and to do ordering numerically
in table model.

wysota
7th July 2009, 11:26
The precision is maintained. You only see the double truncated. If you want the full precision to be displayed, reimplement the delegate and force it to draw all the decimals by modifying the call to QString::number() that takes a precision (6 by default).

nikhilqt
7th July 2009, 11:56
Ok. Can you brief a little which one to reimplement which inturns call QString::number(). I am little confused.

wysota
7th July 2009, 13:22
The easiest way would be to derive from QStyledItemDelegate and reimplement QStyledItemDelegate::displayText().

nikhilqt
7th July 2009, 15:59
Even i reimplement QStyledItemDelegate::displayText(...), the return type is again a string and the sorting happens based on string comparision. ;)

wysota
7th July 2009, 16:13
What exactly did you do?

ChrisW67
8th July 2009, 00:45
Can you let me know how should i maintain the precision and to do ordering numerically
in table model.


If you use QStandardItemModel::setSortRole() to set the role to Qt::EditRole and return a QVariant::Double in that role, and the QVariant::String form in the Qt::DisplayRole, does that achieve your sorting requirement?

nikhilqt
8th July 2009, 08:41
What exactly did you do?

I just looked into the signature and the parameters of the method, as such it returns me the string only. Again if i click on the column header of the tableview it gives me string compare only. correct me if Iam wrong.

nikhilqt
8th July 2009, 08:43
If you use QStandardItemModel::setSortRole() to set the role to Qt::EditRole and return a QVariant:: Double in that role, and the QVariant::String form in the Qt:: DisplayRole, does that achieve your sorting requirement?

I do not edit the contents of the table, I only click on the column header of the tableview, such that the sorting of Ascending and Descending happens.

wysota
8th July 2009, 09:41
I just looked into the signature and the parameters of the method, as such it returns me the string only. Again if i click on the column header of the tableview it gives me string compare only. correct me if Iam wrong.

So you didn't implement anything, just assumed it wouldn't work anyway?

nikhilqt
8th July 2009, 10:26
So you didn't implement anything, just assumed it wouldn't work anyway?

I would rather put it this way, I started with the process and did not get how to change the precision.

QStyledItemDelegate::displaytext(...) takes QVariant and the QLocale.

After setting up this delegate to my model, this displaytext is called for showing the text on the view. But here i stuck up, as how to draw all the decimals.

wysota
8th July 2009, 10:32
Hmm... I even told you which method to use to get the desired output... I really don't understand what is so hard there to understand...


QString myDelegate::displayText(const QVariant &val, const QLocale &locale) const {
if(val.type()==QVariant::Double) return locale.toString(val.toDouble(), 'g', 12); // or QString::number(val.toDouble(), 'g', 12)
return QStyledItemDelegate::displayText(val, locale);
}

ChrisW67
8th July 2009, 11:09
I do not edit the contents of the table, I only click on the column header of the tableview, such that the sorting of Ascending and Descending happens.
This useful?


#include <QtGui>
#include <QDebug>
#include <QStandardItemModel>

int main(int argc, char *argv[])
{

QApplication app(argc, argv);

QStandardItemModel model(10, 2);
model.setSortRole(Qt::EditRole);
for (int row = 0; row < 10; ++row) {
qreal value = row * 1.2345678;
QString text;
text.setNum(value, 'g', 10);

// Column with only a user readable DisplayRole
QStandardItem *item1 = new QStandardItem(text);
model.setItem(row, 0, item1);

// Column with sortable EditRole
QStandardItem *item2 = new QStandardItem(text);
item2->setData(value, Qt::EditRole);
model.setItem(row, 1, item2);
}

QTableView tv;
tv.setModel(&model);
tv.setSortingEnabled(true);
tv.horizontalHeader()->setSortIndicator(0, Qt::AscendingOrder);
tv.horizontalHeader()->setSortIndicator(1, Qt::AscendingOrder);
tv.show();

return app.exec();
}

// vi: sw=4 ts=4 et

Column 1 sorts based on the string representation. Column 2 sorts numerically but displays in default format.

faldzip
8th July 2009, 11:12
for me this is working as it should:


#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QStyledItemDelegate>

class MyDelegate : public QStyledItemDelegate
{
public:
MyDelegate(QObject *parent = 0) : QStyledItemDelegate(parent) { }
QString displayText(const QVariant &value, const QLocale &locale) const {
if (value.type() == QVariant::Double) return locale.toString(value.toDouble(), 'g', 16);
return QStyledItemDelegate::displayText(value, locale);
}
};

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_model = new QStandardItemModel(this);
QStandardItem *item = new QStandardItem;
item->setData(3.8133400354, Qt::DisplayRole);
m_model->appendRow(QList<QStandardItem *>() << item << new QStandardItem("text a"));
item = new QStandardItem;
item->setData(2.123003885, Qt::DisplayRole);
m_model->appendRow(QList<QStandardItem *>() << item << new QStandardItem("text h"));
item = new QStandardItem;
item->setData(2.123003876, Qt::DisplayRole);
m_model->appendRow(QList<QStandardItem *>() << item << new QStandardItem("text c"));
item = new QStandardItem;
item->setData(123.85934000053, Qt::DisplayRole);
m_model->appendRow(QList<QStandardItem *>() << item << new QStandardItem("text a"));
item = new QStandardItem;
item->setData(13.85942403234, Qt::DisplayRole);
m_model->appendRow(QList<QStandardItem *>() << item << new QStandardItem("text f"));
item = new QStandardItem;
item->setData(46.8593400354, Qt::DisplayRole);
m_model->appendRow(QList<QStandardItem *>() << item << new QStandardItem("text g"));
item = new QStandardItem;
item->setData(3.2452334, Qt::DisplayRole);
m_model->appendRow(QList<QStandardItem *>() << item << new QStandardItem("text d"));
item = new QStandardItem;
item->setData(8.4223400354, Qt::DisplayRole);
m_model->appendRow(QList<QStandardItem *>() << item << new QStandardItem("text e"));
ui->tableView->setModel(m_model);
ui->tableView->setItemDelegate(new MyDelegate(this));
}

MainWindow::~MainWindow()
{
delete ui;
}

nikhilqt
8th July 2009, 16:08
It worked. It took little more time to get hang on it. sorry for that. I made wrong in overriding the displayText() method. My new signature of the method acted as overloaded method of that and the call for that displaytext() did not happen until i realize the mistake.:D

Thanks for the patience.:)