使用输入掩码正确输入 phone 数字

Correct input of a phone number with an input mask

问了最后一个问题,关于掩码和如何将光标放在输入文本的末尾,但没有得到答复。试图自己弄清楚,我意识到这个问题被问得很肤浅。所以。我试图深入研究逻辑,查看了不同站点上的示例。

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

我最初的想法是什么 - 当您单击鼠标或获得焦点时,循环检查该行并将光标放在第一个“__”的位置。这个想法非常 quickly 失败了,当我调试了行 ui->lineEdit->text() ,并意识到该行只包含掩码中的字符,没有“填充物”(_)。结果,我得到了 +7()-- 行。下一个想法是这样的,经过多次折磨:我试图想出一些复杂的数学计算,比如从字符串的末尾开始循环,一旦字符串的一部分变得不等于'('或') ' 或 '-' - 计算光标的位置。 (再次考虑字符“()-”)似乎甚至发生了一些事情:

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;
        }
    }

但是还是遇到了一些奇怪的行为,因为当你点击鼠标的时候,光标仍然放在鼠标被戳的地方。尽管将上述开关放入按钮似乎可以正常工作。 我什至尝试处理基本逻辑-当获得焦点时,光标将获得索引4,即它会移动到介绍所需的第一个位置-但这里的情况与上述情况相同。

也许我需要直接使用验证器?现在有一个验证器,这是它的代码:

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

但它用于检查 phone 号码的拼写是否正确。在代码中,我检查了输入字符串的有效性,然后执行必要的逻辑。

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

我能做什么?什么是更有效且最重要的工作解决方案,用于创建正确填写带有掩码的 phone 数字?一般来说,如果没有所有这些“装饰”- 面具执行其功能,但只要需要在程序中输入大量数字,管理人员就不会很高兴需要将鼠标对准 requi红色拨号位置

我 运行 有时也会使用基本的小部件。它们非常适合一般用途,但对于特殊情况或当您确实需要 fast/efficient 重复输入时,它们可能会很麻烦。如果您已付出合理的努力让默认小部件正常运行但仍然无法正常运行,有时最简单的方法就是用火将其杀死并继续:

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 );
    }

};

如果您有现代人对继承的健康反感,那么可以通过安装 Qt-style 事件过滤器来完成类似的事情,而不需要太多努力。但希望这能让您快速测试这种方法是否满足您的需求,或者以其他方式提供另一种探索途径。

您正在调用 text() 方法,根据 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().

所以您要做的就是从模板中找到符号 _ 并将光标设置到它的位置:

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;
}