PDA

View Full Version : Validator for QDoubleSpinBox



ehamberg
14th March 2008, 18:16
Hi,

I have a QTableView with a QAbstractTableModel and a custom delegate for editing the different fields. For one of the fields I have a QDoubleSpinBox and I want to change the default validator to allow both a comma and a dot to be used as a decimal symbol. However the lineEdit() methond in QDoubleSpinBox is protected, so I get an error. What is the easiest way I can change the spinbox' validator?

The code:


void ExpensesDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
if (index.column() == AMOUNT_COLUMN) {
QDoubleSpinBox *amountEditor = qobject_cast<QDoubleSpinBox *>(editor);

amountEditor->lineEdit()->setValidator(new QRegExpValidator(QRegExp("-?[0-9]*[.,]?[0-9]*"), amountEditor)); // <---

amountEditor->setValue(index.model()->data(index, Qt::EditRole).toDouble());

...

jpn
14th March 2008, 18:41
Hmm, at least you can use QObject::findChild() to get around the limitation.

wysota
14th March 2008, 18:44
I think changing the validator is not enough. The spinbox has its own internal validation method - valueFromText. It's enough if you reimplement it and convert the text to double there, no need for a validator.

ehamberg
15th March 2008, 12:37
I think changing the validator is not enough. The spinbox has its own internal validation method - valueFromText. It's enough if you reimplement it and convert the text to double there, no need for a validator.

The problem is just that without altering the validator, one can't type a comma. Here's the solution I ended up with:


class AmountSpinBox : public QDoubleSpinBox
{
Q_OBJECT

public:
AmountSpinBox(QWidget *parent = 0) : QDoubleSpinBox(parent)
{
m_decimalSymbol = KGlobal::locale()->monetaryDecimalSymbol();

// regexp for the validator:
// 1) optional minus sign then 0 or more digits
// 2) dot or locale decimal symbol
// 3) 0, 1 or 2 digits
lineEdit()->setValidator(new QRegExpValidator(QRegExp("-?[0-9]*[." +
(m_decimalSymbol != "." ? m_decimalSymbol : "") // add locale deciman symbol if it's not a dot
+ "]?[0-9]{,2}"), this));

setAlignment(Qt::AlignRight);
setButtonSymbols(QDoubleSpinBox::PlusMinus);
setRange(-9999999999.99, 9999999999.99);
}

private:
double valueFromText(const QString &text) const
{
QString m_decimalSymbol = KGlobal::locale()->monetaryDecimalSymbol();
QString temp = text;
temp.replace(QRegExp(m_decimalSymbol), "."); // replace locale decimal symbol with dot before toDouble()

return temp.toDouble();
}

QValidator::State validate ( QString & input, int & pos ) const
{
// let's *really* trust the validator :-)
return QValidator::Acceptable;
}

QString m_decimalSymbol;
};