Russian Qt Forum

Qt => Общие вопросы => Тема начата: Icoz от Февраль 28, 2008, 20:28



Название: [qt4.3] Проблемы с валидаторами
Отправлено: Icoz от Февраль 28, 2008, 20:28
Есть куча QLineEdit, к которым подцеплены QDoubleValidator. При смене фокуса или нажатии ентера QLineEdit генерирует сигнал void editingFinished (), который вызывается ТОЛЬКО когда ввод верен.
Мне же надо прямо обратное, чтобы сразу матюгнуть юзверя, что "ай-ай-ай! плохую циферку ввел"...
Собственно вопрос: КАК?
Уже пробовал и такую вещь:
Код:
void MainWidget::lineedit_changed(const QString &str)
{
int i =0;
QString st = str;
if (lineedit->validator()->validate(st, i) != QValidator::Invalid)
lineedit->setStyleSheet("background: green");
else
lineedit->setStyleSheet("background: red");
}
Но у меня всегда только зеленый цвет получается... :( Может я в валидаторе что-то накосячил?
Код:
	QDoubleValidator *val = new QDoubleValidator(0, 100, 3, lineedit);
val->setNotation( QDoubleValidator::ScientificNotation);
lineedit->setValidator(val);
connect(lineedit,SIGNAL(editingFinished()),this,SLOT(lineedit_entered()));
connect(lineedit,SIGNAL(textChanged( const QString &)),this,SLOT(lineedit_changed( const QString &)));


Название: Re: [qt4.3] Проблемы с валидаторами
Отправлено: Вячеслав от Февраль 28, 2008, 20:54
ну я-б сварганил наследника QDoubleValidator'a и в validate ставил цвет ....
А вообще lineedit_changed у тебя вызываеться или если ввод неверен,то валидатор не дает вводить фигню?

PS Вскрытие(быстрое дошкуривание примера lineedits) показало - если стоит валидатор,фигня не вводится и слот не вызываеться ;) Таки делай наследника ;)


Название: Re: [qt4.3] Проблемы с валидаторами
Отправлено: Icoz от Февраль 28, 2008, 23:12
В том-то и дело, что все вызывается, а валидатор ДАЕТ вводить фигню! :( Но я думаю, что это из-за того, что он думает, что введенное значение есть QValidator::Intermediate

Проблему решил следующим образом.
Использовал QSignalMapper для работы с кучей QLineEdit'ов так:
1) в конструкторе
Код:
	signalMapper = new QSignalMapper(this);
setConnectForSignalMapper(this);
connect(signalMapper, SIGNAL(mapped(QWidget *)), this, SLOT(signalMapper_mapped(QWidget *)));
2) setConnectForSignalMapper(this); - это автоматическое подключение всех QLineEdit, которые являются потомками this на любом уровне вложения
Код:
void MainWindowImpl::setConnectForSignalMapper(QWidget *wgt)
{
foreach (QWidget *wgt2, wgt->findChildren<QWidget *>()){
if (wgt2->children().size())
setConnectForSignalMapper(wgt2);
QLineEdit *le =qobject_cast<QLineEdit *>(wgt2);
if (le != 0){
connect(le,SIGNAL(textChanged( const QString &)),signalMapper, SLOT(map()));
signalMapper->setMapping(le,le);
}
}
}
3) и непосредственно обработчик:
Код:
void MainWindowImpl::signalMapper_mapped(QWidget *wgt)
{
QLineEdit *le = qobject_cast<QLineEdit *>(wgt);
if (le == 0) return;
int i =0;
QString st = le->text();
if (le->validator()->validate(st, i) == QValidator::Acceptable){
le->setStyleSheet("background: white");
btnCalc->setEnabled(true); // разблокируем кнопку
}else{
le->setStyleSheet("background: red");
btnCalc->setEnabled(false); // блокируем кнопку
}
fileIsSaved = false;
}


Название: Re: [qt4.3] Проблемы с валидаторами
Отправлено: Вячеслав от Февраль 28, 2008, 23:35
examples\widgets\lineedits\window.cpp
Код:
#include <QtGui>
#include <QDebug>

#include "window.h"


Window::Window()
{
    QGroupBox *echoGroup = new QGroupBox(tr("Echo"));

    QLabel *echoLabel = new QLabel(tr("Mode:"));
    QComboBox *echoComboBox = new QComboBox;
    echoComboBox->addItem(tr("Normal"));
    echoComboBox->addItem(tr("Password"));
    echoComboBox->addItem(tr("PasswordEchoOnEdit"));
    echoComboBox->addItem(tr("No Echo"));

    echoLineEdit = new QLineEdit;
    echoLineEdit->setFocus();

    QGroupBox *validatorGroup = new QGroupBox(tr("Validator"));

    QLabel *validatorLabel = new QLabel(tr("Type:"));
    QComboBox *validatorComboBox = new QComboBox;
    validatorComboBox->addItem(tr("No validator"));
    validatorComboBox->addItem(tr("Integer validator"));
    validatorComboBox->addItem(tr("Double validator"));

    validatorLineEdit = new QLineEdit;

    QGroupBox *alignmentGroup = new QGroupBox(tr("Alignment"));

    QLabel *alignmentLabel = new QLabel(tr("Type:"));
    QComboBox *alignmentComboBox = new QComboBox;
    alignmentComboBox->addItem(tr("Left"));
    alignmentComboBox->addItem(tr("Centered"));
    alignmentComboBox->addItem(tr("Right"));

    alignmentLineEdit = new QLineEdit;

    QGroupBox *inputMaskGroup = new QGroupBox(tr("Input mask"));

    QLabel *inputMaskLabel = new QLabel(tr("Type:"));
    QComboBox *inputMaskComboBox = new QComboBox;
    inputMaskComboBox->addItem(tr("No mask"));
    inputMaskComboBox->addItem(tr("Phone number"));
    inputMaskComboBox->addItem(tr("ISO date"));
    inputMaskComboBox->addItem(tr("License key"));

    inputMaskLineEdit = new QLineEdit;

    QGroupBox *accessGroup = new QGroupBox(tr("Access"));

    QLabel *accessLabel = new QLabel(tr("Read-only:"));
    QComboBox *accessComboBox = new QComboBox;
    accessComboBox->addItem(tr("False"));
    accessComboBox->addItem(tr("True"));

    accessLineEdit = new QLineEdit;

    connect(echoComboBox, SIGNAL(activated(int)),
            this, SLOT(echoChanged(int)));
    connect(validatorComboBox, SIGNAL(activated(int)),
            this, SLOT(validatorChanged(int)));
    connect(alignmentComboBox, SIGNAL(activated(int)),
            this, SLOT(alignmentChanged(int)));
    connect(inputMaskComboBox, SIGNAL(activated(int)),
            this, SLOT(inputMaskChanged(int)));
    connect(accessComboBox, SIGNAL(activated(int)),
            this, SLOT(accessChanged(int)));

connect(validatorLineEdit,SIGNAL(textChanged( const QString &)),this,SLOT(validate_changed( const QString &)));

    QGridLayout *echoLayout = new QGridLayout;
    echoLayout->addWidget(echoLabel, 0, 0);
    echoLayout->addWidget(echoComboBox, 0, 1);
    echoLayout->addWidget(echoLineEdit, 1, 0, 1, 2);
    echoGroup->setLayout(echoLayout);

    QGridLayout *validatorLayout = new QGridLayout;
    validatorLayout->addWidget(validatorLabel, 0, 0);
    validatorLayout->addWidget(validatorComboBox, 0, 1);
    validatorLayout->addWidget(validatorLineEdit, 1, 0, 1, 2);
    validatorGroup->setLayout(validatorLayout);

    QGridLayout *alignmentLayout = new QGridLayout;
    alignmentLayout->addWidget(alignmentLabel, 0, 0);
    alignmentLayout->addWidget(alignmentComboBox, 0, 1);
    alignmentLayout->addWidget(alignmentLineEdit, 1, 0, 1, 2);
    alignmentGroup-> setLayout(alignmentLayout);

    QGridLayout *inputMaskLayout = new QGridLayout;
    inputMaskLayout->addWidget(inputMaskLabel, 0, 0);
    inputMaskLayout->addWidget(inputMaskComboBox, 0, 1);
    inputMaskLayout->addWidget(inputMaskLineEdit, 1, 0, 1, 2);
    inputMaskGroup->setLayout(inputMaskLayout);

    QGridLayout *accessLayout = new QGridLayout;
    accessLayout->addWidget(accessLabel, 0, 0);
    accessLayout->addWidget(accessComboBox, 0, 1);
    accessLayout->addWidget(accessLineEdit, 1, 0, 1, 2);
    accessGroup->setLayout(accessLayout);

    QGridLayout *layout = new QGridLayout;
    layout->addWidget(echoGroup, 0, 0);
    layout->addWidget(validatorGroup, 1, 0);
    layout->addWidget(alignmentGroup, 2, 0);
    layout->addWidget(inputMaskGroup, 0, 1);
    layout->addWidget(accessGroup, 1, 1);
    setLayout(layout);

    setWindowTitle(tr("Line Edits"));
}

void Window::echoChanged(int index)
{
    switch (index) {
    case 0:
        echoLineEdit->setEchoMode(QLineEdit::Normal);
        break;
    case 1:
        echoLineEdit->setEchoMode(QLineEdit::Password);
        break;
    case 2:
    echoLineEdit->setEchoMode(QLineEdit::PasswordEchoOnEdit);
        break;
    case 3:
        echoLineEdit->setEchoMode(QLineEdit::NoEcho);
    }
}

void Window::validatorChanged(int index)
{
    switch (index) {
    case 0:
        validatorLineEdit->setValidator(0);
        break;
    case 1:
        validatorLineEdit->setValidator(new QIntValidator(
            validatorLineEdit));
        break;
    case 2:
        validatorLineEdit->setValidator(new QDoubleValidator(-999.0,
            999.0, 2, validatorLineEdit));
    }

    validatorLineEdit->clear();
}

void Window::alignmentChanged(int index)
{
    switch (index) {
    case 0:
        alignmentLineEdit->setAlignment(Qt::AlignLeft);
        break;
    case 1:
        alignmentLineEdit->setAlignment(Qt::AlignCenter);
        break;
    case 2:
    alignmentLineEdit->setAlignment(Qt::AlignRight);
    }
}

void Window::inputMaskChanged(int index)
{
    switch (index) {
    case 0:
        inputMaskLineEdit->setInputMask("");
        break;
    case 1:
        inputMaskLineEdit->setInputMask("+99 99 99 99 99;_");
        break;
    case 2:
        inputMaskLineEdit->setInputMask("0000-00-00");
        inputMaskLineEdit->setText("00000000");
        inputMaskLineEdit->setCursorPosition(0);
        break;
    case 3:
        inputMaskLineEdit->setInputMask(">AAAAA-AAAAA-AAAAA-AAAAA-AAAAA;#");
    }
}

void Window::accessChanged(int index)
{
    switch (index) {
    case 0:
        accessLineEdit->setReadOnly(false);
        break;
    case 1:
        accessLineEdit->setReadOnly(true);
    }
}

void Window::validate_changed(const QString &str)
{
qDebug() << "vc "<<str;
}

Это то что я делал ... Таки при выбранном qdoublevalidatore в дебаг выдаеться vc "" и ничего более из символов (окромя цифр и ,)
Коментарии ?


Название: Re: [qt4.3] Проблемы с валидаторами
Отправлено: Icoz от Март 05, 2008, 12:56
Все дело в нотации, которую ты выставляешь для QDoubleValidator!
Если у тебя стоит val->setNotation(QDoubleValidator::ScientificNotation), то число может вводится в научном формате, то есть 123.342e-21. Кстати, даже в
StandardNotation у тебя должны восприниматься и точки, и запятые!


Название: Re: [qt4.3] Проблемы с валидаторами
Отправлено: yoyo от Март 06, 2008, 10:02
Необходимого поведения с запятыми и точками при переводе QString  в double можно добиться настроив локаль:

Код:
  QLocale::setDefault(QLocale::C);
  d = QString( "1234,56" ).toDouble(&ok); // ok == false