How to set Input Mask and QValidator to a QLineEdit at a time in Qt?

后端 未结 5 1398
一生所求
一生所求 2020-12-31 21:14

I want a line edit which accepts an ip address. If I give input mask as:

ui->lineEdit->setInputMask(\"000.000.000.000\");

It is accep

相关标签:
5条回答
  • 2020-12-31 21:21

    For those who wonder about the following hint in the QT doku:

    To get range control (e.g., for an IP address) use masks together with validators.

    In this case the validator needs to take care of blanks. My solution, adapted from lpapp's answer and this Qt forum post, therefore reads:

    QString ipRange = "(([ 0]+)|([ 0]*[0-9] *)|([0-9][0-9] )|([ 0][0-9][0-9])|(1[0-9][0-9])|([2][0-4][0-9])|(25[0-5]))";
    // You may want to use QRegularExpression for new code with Qt 5 (not mandatory).
    QRegExp ipRegex ("^" + ipRange
                     + "\\." + ipRange
                     + "\\." + ipRange
                     + "\\." + ipRange + "$");
    QRegExpValidator *ipValidator = new QRegExpValidator(ipRegex, this);
    lineEdit->setValidator(ipValidator);
    lineEdit->setInputMask("000.000.000.000");
    // Avoid having to move cursor before typing
    linEdit->setCursorPosition(0);
    

    I am a beginner at using regular expressions, so feel free to recommend improvements.

    0 讨论(0)
  • 2020-12-31 21:30

    The easier method is try inputmask option

    ui->lineEdit_IP->setInputMask( "000.000.000.000" );
    

    and in your validation code use the following simple condition

    QHostAddress myIP;
       if( myIP.setAddress( ui->lineEdit_IP->text()) )
       qDebug()<<"Valid IP Address";
       else
       qDebug()<<"Invalid IP address";
    
    0 讨论(0)
  • 2020-12-31 21:32

    Hi I had almost the same problem. Solutions with inputmask or regExp were unsatisfactory. I decided to make my own bicycle.

    Header:

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QLineEdit>
    #include <QFrame>
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    private:
        Ui::MainWindow *ui;
    };
    
    //=============================================================================
    class CustomIpEditor : public QFrame
    {
        Q_OBJECT
    public:
        explicit CustomIpEditor(QWidget *parent = 0);
        virtual ~CustomIpEditor() {}
    };
    
    //=============================================================================
    class CustomLineEdit : public QLineEdit
    {
        Q_OBJECT
    public:
        explicit CustomLineEdit(const QString & contents = "", QWidget *parent = 0);
        virtual ~CustomLineEdit() {}
    
    signals:
        void jumpForward();
        void jumpBackward();
    
    public slots:
        void jumpIn();
    
    protected:
        virtual void focusInEvent(QFocusEvent *event);
        virtual void keyPressEvent(QKeyEvent * event);
        virtual void mouseReleaseEvent(QMouseEvent *event);
    
    private:
        bool selectOnMouseRelease;
    };
    
    #endif // MAINWINDOW_H
    

    Source:

    #include <QVBoxLayout>
    #include <QKeyEvent>
    
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        centralWidget()->setLayout(new QVBoxLayout);
    
        CustomIpEditor *myed = new CustomIpEditor;
        centralWidget()->layout()->addWidget(myed);
    
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    //=============================================================================
    CustomLineEdit::CustomLineEdit(const QString & contents, QWidget *parent) :
        QLineEdit(contents, parent), selectOnMouseRelease(false)
    {
        QIntValidator *valid = new QIntValidator(0, 255, this);
        setValidator(valid);
    }
    
    void CustomLineEdit::jumpIn()
    {
        setFocus();
    
        selectOnMouseRelease = false;
        selectAll();
    }
    
    void CustomLineEdit::focusInEvent(QFocusEvent *event)
    {
        QLineEdit::focusInEvent(event);
        selectOnMouseRelease = true;
    }
    
    void CustomLineEdit::keyPressEvent(QKeyEvent * event)
    {
        int key = event->key();
        int cursorPos = cursorPosition();
    
        // Jump forward by Space
        if (key == Qt::Key_Space) {
            emit jumpForward();
            event->accept();
            return;
        }
    
        // Jump Backward only from 0 cursor position
        if (cursorPos == 0) {
            if ((key == Qt::Key_Left) || (key == Qt::Key_Backspace)) {
                emit jumpBackward();
                event->accept();
                return;
            }
        }
    
        // Jump forward from last postion by right arrow
        if (cursorPos == text().count()) {
            if (key == Qt::Key_Right) {
                emit jumpForward();
                event->accept();
                return;
            }
        }
    
        // After key is placed cursor has new position
        QLineEdit::keyPressEvent(event);
        int freshCurPos = cursorPosition();
    
        if ((freshCurPos == 3) && (key != Qt::Key_Right))
            emit jumpForward();
    }
    
    void CustomLineEdit::mouseReleaseEvent(QMouseEvent *event)
    {
        if(!selectOnMouseRelease)
            return;
    
        selectOnMouseRelease = false;
        selectAll();
    
        QLineEdit::mouseReleaseEvent(event);
    }
    
    //=============================================================================
    void makeCommonStyle(QLineEdit* line) {
        line->setContentsMargins(0, 0, 0, 0);
        line->setAlignment(Qt::AlignCenter);
        line->setStyleSheet("QLineEdit { border: 0px none; }");
        line->setFrame(false);
        line->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
    }
    
    QLineEdit* makeIpSpliter() {
        QLineEdit *spliter = new QLineEdit(".");
        makeCommonStyle(spliter);
    
        spliter->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
        spliter->setMaximumWidth(10);
        spliter->setReadOnly(true);
        spliter->setFocusPolicy(Qt::NoFocus);
        return spliter;
    }
    
    CustomIpEditor::CustomIpEditor(QWidget *parent) :
        QFrame(parent)
    {
        setContentsMargins(0, 0, 0, 0);
        setStyleSheet("QFrame { background-color: white;  border: 1px solid white; border-radius: 15px; }");
    
        QList <CustomLineEdit *>  lines;
        QList <CustomLineEdit *>::iterator linesIterator;
    
        lines.append(new CustomLineEdit);
        lines.append(new CustomLineEdit);
        lines.append(new CustomLineEdit);
        lines.append(new CustomLineEdit);
    
        QHBoxLayout *mainLayout = new QHBoxLayout;
        mainLayout->setSpacing(0);
        setLayout(mainLayout);
    
        for (linesIterator = lines.begin(); linesIterator != lines.end(); ++linesIterator) {
            makeCommonStyle(*linesIterator);
            mainLayout->addWidget(*linesIterator);
    
            if (*linesIterator != lines.last()) {
                connect(*linesIterator, &CustomLineEdit::jumpForward,
                        *(linesIterator+1), &CustomLineEdit::jumpIn);
                mainLayout->addWidget(makeIpSpliter());
            }
            if (*linesIterator != lines.first()) {
                connect(*linesIterator, &CustomLineEdit::jumpBackward,
                        *(linesIterator-1), &CustomLineEdit::jumpIn);
            }
        }
    
    }
    
    0 讨论(0)
  • 2020-12-31 21:44

    In accordance to Arun Kumar K S's answer:

    If myIP.setAddress() was successfull, you can write the ip back to the line edit as a formatted string:

    ui->lineEdit->setText(myIP->toString());
    

    Consequently, you don't neccessarily need to set a mask (nor a validator or regex).

    Note setAddress() writes/overwrites your myIP also if it fails to read the ip. Thus, calling toString() in this case results in an empty string.

    0 讨论(0)
  • 2020-12-31 21:47

    It is accepting value greater than 255.

    Absolutely, because '0' means this:

    ASCII digit permitted but not required.
    

    As you can see, this is not your cup of tea. There are at least the following ways to circumvent it:

    • Write a custom validator

    • Use regex

    • Split the input into four entries and validate each entry on its own while still having visual delimiters between the entries.

    The regex solution would be probably the quick, but also ugliest IMHO:

    QString ipRange = "(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])";
    // You may want to use QRegularExpression for new code with Qt 5 (not mandatory).
    QRegExp ipRegex ("^" + ipRange
                     + "\\." + ipRange
                     + "\\." + ipRange
                     + "\\." + ipRange + "$");
    QRegExpValidator *ipValidator = new QRegExpValidator(ipRegex, this);
    lineEdit->setValidator(ipValidator);
    

    Disclaimer: this will only validate IP4 addresses properly, so it will not work for IP6 should you need that in the future.

    0 讨论(0)
提交回复
热议问题