How to enable a submit button after multiple form fields have been verified.



  • Hello again,

    This post is an unrelated followup to this post:

    http://developer.qt.nokia.com/forums/viewthread/4850

    If I have a form with 4 line edits and a disabled ok button that I would like to enable once the lineedits are all validated, how do I check to verify all of the lineedits are validated? Do I need to have a variable in the form class that indicates the number of validated fields and check that every time I receive an editingFinished() signal? (If they're all validated, then it would have a value of 4 and the ok button would enable). Is there a better way?

    Thanks!!



  • You should connect signal "textChanged() ":http://doc.qt.nokia.com/4.7/qlineedit.html#textChanged of all four line edits to a single slot. In that slot, check if all four line edits are filled with some text and set the ok button enabled on the result of your calcualtions. It would look something like this:

    @
    YourDialog::YourDialog(QWidget *parent)
    {
    connect(ui->lineEdit1, SIGNAL(textChanged()), this, SLOT(checkLineEdits()));
    connect(ui->lineEdit2, SIGNAL(textChanged()), this, SLOT(checkLineEdits()));
    connect(ui->lineEdit3, SIGNAL(textChanged()), this, SLOT(checkLineEdits()));
    connect(ui->lineEdit4, SIGNAL(textChanged()), this, SLOT(checkLineEdits()));
    }

    void YourDialog::checkLineEdits()
    {
    bool ok = !ui->lineEdit1->text().isEmpty()
    && !ui->lineEdit2->text().isEmpty()
    && !ui->lineEdit3->text().isEmpty()
    && !ui->lineEdit4->text().isEmpty();

    ui->okButton->setEnabled(ok);
    

    }
    @



  • Yes, do as Volker suggests. This is a common pattern that you will likely use quite often.



  • The method Volker suggested is the safe way to do it and as I understand it uses some kind of state machine for storing the actual state of validity therefore it does not cause significant overhead even if your validation is resource hungry.



  • I have seen this same question not too long ago on this forum. Not sure it was the same one asking though.

    While Volker's code is absolutely right, personally, I find something like this more readable:

    @
    void YourDialog::checkLineEdits()
    {
    bool ok(true);
    ok &= !ui->lineEdit1->text().isEmpty();
    ok &= !ui->lineEdit2->text().isEmpty();
    ok &= !ui->lineEdit3->text().isEmpty();
    ok &= !ui->lineEdit4->text().isEmpty();

    ui->okButton->setEnabled(ok);
    

    }
    @

    And I know people here are going to disagree with me. :-)
    Of course, variations are possible too, for instance one where you iterate over all QLineEdits (no matter how many there are):

    @
    void YourDialog::checkLineEdits()
    {
    bool ok(true);
    QList<QLineEdit*> lineEditList = findChildren<QLineEdit*>();
    foreach (QLineEdit* le, lineEditList)
    ok &= !le->text().isEmpty();

    ui->okButton->setEnabled(ok);
    

    }
    @



  • It makes little sense to use bitwise operators on a bool, doesn't it? :P



  • [quote author="peppe" date="1302002385"]It makes little sense to use bitwise operators on a bool, doesn't it? :P[/quote]

    How would you do then? On linux you can use '*=' instead of '&=' if both operands are bool, but I was told by an expert that (at least some) windows compiler just cannot stand such a notation.



  • I was just punning on:
    [quote]And I know people here are going to disagree with me. :-)[/quote]

    In C unfortunately there's no short-circuiting operator &&= (which would be required in this case).



  • [quote author="peppe" date="1302002385"]It makes little sense to use bitwise operators on a bool, doesn't it? :P[/quote]

    Ah, well, they just are very short. Just one bit to compare bitwise. It works nonetheless.

    If you want to do it "right", I guess you'd have to do this:
    @
    void YourDialog::checkLineEdits()
    {
    bool ok(true);
    ok = ok && !ui->lineEdit1->text().isEmpty();
    ok = ok && !ui->lineEdit2->text().isEmpty();
    ok = ok && !ui->lineEdit3->text().isEmpty();
    ok = ok && !ui->lineEdit4->text().isEmpty();

    ui->okButton->setEnabled(ok);
    

    }
    @

    Does that get more readable? Not really, I think.

    P.S. I was expecting comments on this not being efficient, actually. :-)



  • [quote author="VCsala" date="1301955029"]The method Volker suggested is the safe way to do it and as I understand it uses some kind of state machine for storing the actual state of validity therefore it does not cause significant overhead even if your validation is resource hungry.[/quote]

    There is no state machine involved. The code always checks all four line edits. There may be some short circuiting by the compiler, if the first check is false, the complete expression is false, so there is no need to calculate the rest.



  • [quote author="Volker" date="1302021381"][quote author="VCsala" date="1301955029"]The method Volker suggested is the safe way to do it and as I understand it uses some kind of state machine for storing the actual state of validity therefore it does not cause significant overhead even if your validation is resource hungry.[/quote]

    There is no state machine involved. The code always checks all four line edits. There may be some short circuiting by the compiler, if the first check is false, the complete expression is false, so there is no need to calculate the rest.[/quote]

    However, if you want to have more complex check on the input field (and not only checking if it is empty or not) and you use validator (which is a more generic solution for this use case) then you have validity states (and in this case the validation itself can be resource and time consuming). As I know even in this case the above pattern is safe as the states are recalculated only if the field has been changed.



  • Thanks for all the input! QT certainly has an active AND helpful community...something that can be difficult to find in combination.



  • Don't forget good looking too ;-)

    Good luck with your project!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.