Home > Blockchain >  Correct input of a phone number with an input mask
Correct input of a phone number with an input mask

Time:04-24

Asked the last question, regarding the mask and how to put the cursor at the end of the typed text, but did not receive an answer. Trying to figure it out on my own, I realized that the question was asked very superficially. So. I tried to delve into the logic, looked at examples on different sites.

ui->lineEdit_newClientPhone->setInputMask(" 7\\(999\\)999\\-99\\-99;_");

enter image description here

What was my original idea - when you click the mouse, or when you get focus, check the line in a loop and put the cursor in the place of the first "__". The idea failed very quickly, as soon as I debugged the line ui->lineEdit->text() , and realized that the line consists only of the characters that are in the mask, without the "filler" (_). As a result, I had the line 7()--. The next idea was this, after much torment: I tried to come up with some complex mathematical calculations, like going through a cycle from the end of the string, as soon as part of the string becomes not equal to '(' or ')' or '-' - calculate the position cursor. (considering, again, the characters "( ) -") It seems that something even happened:

if(event->type() == QEvent::MouseButtonPress){
        int a = ui->lineEdit_newClientPhone->text().length();
        switch(a){
        case 6: case 7: case 8:
            ui->lineEdit_newClientPhone->setCursorPosition(a - 3);
            break;
        case 9: case 10:
            ui->lineEdit_newClientPhone->setCursorPosition(a - 2);
            break;
        case 11: case 12:
            ui->lineEdit_newClientPhone->setCursorPosition(a - 1);
            break;
        case 13: case 14:
            ui->lineEdit_newClientPhone->setCursorPosition(a);
            break;
        }
    }

But still hit some strange behavior, because when you click the mouse, the cursor is STILL put in the place where the mouse was poked. Despite the fact that putting the above switch into a button seems to work correctly. I even tried to process elementary logic - when receiving focus, the cursor would receive index 4, that is, it would move to the first position necessary for introduction - but here the situation is the same as described above.

Maybe i need to use the validator directly with the line? Now there is a validator, here is its code:

QRegularExpression numberRegex ("^\\ \\d{1,1}\\(\\d{3,3}\\)\\d{3,3}\\-\\d{2,2}\\-\\d{2,2}$");
QRegularExpressionValidator *numberValidator = new QRegularExpressionValidator (numberRegex);

But it is used to check the correct spelling of a phone number. Further in the code, I check the validity of the entered string and then perform the necessary logic.

if(numberValidator->validate(a, b) == QValidator::Acceptable){
    ...
}

And what can I do? What is a more competent, and most importantly working, solution for creating the correct filling in of a phone number with a mask? In general, without all these "frills" - the mask performs its functions, but insofar as a large number of numbers will need to be entered in the program, managers will not be very happy with the need to aim the mouse at the required place for dialing.

CodePudding user response:

You are calling text() method, according to Qt doc:

When an input mask is set, the text() method returns a modified copy of the line edit content where all the blank characters have been removed. The unmodified content can be read using displayText().

So all you should do is finding symbol _ from template and setting cursor to it's position:

if(event->type() == QEvent::MouseButtonPress)
{
    int pos = ui->lineEdit_newClientPhone->displayText()
                      .indexOf("_");
    int last_pos = ui->lineEdit_newClientPhone->displayText().length();
    ui->lineEdit_newClientPhone->setCursorPosition(
        pos == -1 ? last_pos : pos
        );
    return true;
}

CodePudding user response:

I run into this sometimes as well with the basic widgets. They are great for general purposes, but for special cases or when you really need fast/efficient repeated input like you want, they can be cumbersome. If you've put in a reasonable effort to get the default widgets to behave but still can't, sometimes the easiest way is to just kill it with fire and move on:

class CQLineEditPhoneClickEntry : public QLineEdit
{
    Q_OBJECT
public:
    explicit CQLineEditPhoneClickEntry( QWidget* pParent = 0 )
        : QLineEdit( pParent )
    {
        setInputMask( " 7\\(999\\)999\\-99\\-99;_" );
    }

    virtual void mousePressEvent ( QMouseEvent* pEvent ) //override
    {
        QPoint pressPoint = pEvent->pos();

        if( text().count() == 6 )
        {
            setCursorPosition(4);
            return;
        }

        if( pressPoint.x() > 90 ) // in reality do something less hacky to support high dpi, etc.
        {
            setCursorPosition(4);
            return;
        }

        QLineEdit::mousePressEvent( pEvent );
    }

};

If you have a modern person's healthy aversion to inheritance, then a similar thing can be done using by installing a Qt-style event filter without too much effort. But hopefully this will let you quickly test if this approach works for your needs or otherwise provide another avenue of exploration towards something that does.

  •  Tags:  
  • c qt
  • Related