Qt实现IP输入框

​​​​​1、IP输入框组成

4个QLineEdit用于输入,3个QLabel用于显示小数点。

2、事件消息处理

installEventFilter捕获QLineEdit事件,重写eventFilter用于事件响应。
   A、删除键Qt::Key_Backspace:若当前QLineEdit中光标左侧没有数据,则移到前一个QLineEdit中并删除一位;否则只删除一位。
   B、左移键Qt::Key_Left:若当前QLineEdit中光标左侧没有数据,则移到前一个QLineEdit;否则只前移一位。
   C、右移键Qt::Key_Right:若当前QLineEdit中光标右侧没有数据,则移到下一个QLineEdit;否则只后移一位。
   D、英文小数点Qt::Key_Period:若当前QLineEdit不为空,则移到到下一个QLineEdit并全选;否则不移动。
   E、中文句号:事件类型不是QEvent::KeyPress而是QEvent::InputMethod,判断数据数据是否含中文句号,若当前QLineEdit不为空,则移到到下一个QLineEdit并全选;否则不移动。
   F、屏蔽QLineEdit右键菜单,处理Ctrl+V粘贴键盘事件。


 3、代码

#ifndef QIPEdit_H
#define QIPEdit_H

#include <QWidget>
#include <QLineEdit>
#include <QLabel>

class QIPEdit : public QWidget
{
    Q_OBJECT
public:
    explicit QIPEdit(QWidget *parent = nullptr);
    QSize sizeHint() const override;
    QSize minimumSizeHint() const override;
    QString GetIP() const;
protected:
    bool eventFilter(QObject *watched, QEvent *event) override;
private slots:
    void textChanged(const QString &text);
public slots:
    void clear();
    bool setIP(const QString& strIP);

    //设置背景颜色
    void setBgColor(const QString &bgColor);
    //设置边框颜色
    void setBorderColor(const QString &borderColor);
    //设置边框圆角角度
    void setBorderRadius(int borderRadius);
private:
    void setQss();

private:
    QLabel* m_labelDot1;
    QLabel* m_labelDot2;
    QLabel* m_labelDot3;

    QLineEdit* m_lineEditIP1;
    QLineEdit* m_lineEditIP2;
    QLineEdit* m_lineEditIP3;
    QLineEdit* m_lineEditIP4;

    QString m_strIP;
    QString m_bgColor;              //背景颜色
    QString m_borderColor;          //边框颜色
    int m_borderRadius;             //边框圆角角度
};

#endif // QIPEdit_H
#include "QIPEdit.h"
#include <QRegExp>
#include <QRegExpValidator>
#include <QApplication>
#include <QClipboard>
#include <QLayout>
#include <QEvent>
#include <QKeyEvent>
#include <QDebug>

QIPEdit::QIPEdit(QWidget *parent) : QWidget(parent)
{
    m_bgColor = "#FFFFFF";
    m_borderColor = "#A6B5B8";
    m_borderRadius = 10;

    m_labelDot1 = new QLabel(this);
    m_labelDot1->setAlignment(Qt::AlignCenter);
    m_labelDot1->setText(".");

    m_labelDot2 = new QLabel(this);
    m_labelDot2->setAlignment(Qt::AlignCenter);
    m_labelDot2->setText(".");

    m_labelDot3 = new QLabel(this);
    m_labelDot3->setAlignment(Qt::AlignCenter);
    m_labelDot3->setText(".");

    m_lineEditIP1 = new QLineEdit;
    m_lineEditIP1->setObjectName("lineEditIP1");
    m_lineEditIP1->setAlignment(Qt::AlignCenter);
    m_lineEditIP1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    connect(m_lineEditIP1, SIGNAL(textChanged(QString)), this, SLOT(textChanged(QString)));


    m_lineEditIP2 = new QLineEdit;
    m_lineEditIP2->setObjectName("lineEditIP2");
    m_lineEditIP2->setAlignment(Qt::AlignCenter);
    m_lineEditIP2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    connect(m_lineEditIP2, SIGNAL(textChanged(QString)), this, SLOT(textChanged(QString)));

    m_lineEditIP3 = new QLineEdit;
    m_lineEditIP3->setObjectName("lineEditIP3");
    m_lineEditIP3->setAlignment(Qt::AlignCenter);
    m_lineEditIP3->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    connect(m_lineEditIP3, SIGNAL(textChanged(QString)), this, SLOT(textChanged(QString)));

    m_lineEditIP4 = new QLineEdit;
    m_lineEditIP4->setObjectName("lineEditIP4");
    m_lineEditIP4->setAlignment(Qt::AlignCenter);
    m_lineEditIP4->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    connect(m_lineEditIP4, SIGNAL(textChanged(QString)), this, SLOT(textChanged(QString)));


    QRegExp regExp("(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)");
    QRegExpValidator *validator = new QRegExpValidator(regExp, this);
    m_lineEditIP1->setValidator(validator);
    m_lineEditIP2->setValidator(validator);
    m_lineEditIP3->setValidator(validator);
    m_lineEditIP4->setValidator(validator);

    m_lineEditIP1->setContextMenuPolicy(Qt::NoContextMenu);
    m_lineEditIP2->setContextMenuPolicy(Qt::NoContextMenu);
    m_lineEditIP3->setContextMenuPolicy(Qt::NoContextMenu);
    m_lineEditIP4->setContextMenuPolicy(Qt::NoContextMenu);

    m_lineEditIP1->installEventFilter(this);
    m_lineEditIP2->installEventFilter(this);
    m_lineEditIP3->installEventFilter(this);
    m_lineEditIP4->installEventFilter(this);

    QFrame *frame = new QFrame(this);
    frame->setObjectName("frameIP");

    setQss();

    QVBoxLayout *verticalLayout = new QVBoxLayout(this);
    verticalLayout->setMargin(0);
    verticalLayout->setSpacing(0);
    verticalLayout->addWidget(frame);

    QHBoxLayout *layout = new QHBoxLayout(frame);
    layout->setMargin(0);
    layout->setSpacing(0);
    layout->addWidget(m_lineEditIP1);
    layout->addWidget(m_labelDot1);
    layout->addWidget(m_lineEditIP2);
    layout->addWidget(m_labelDot2);
    layout->addWidget(m_lineEditIP3);
    layout->addWidget(m_labelDot3);
    layout->addWidget(m_lineEditIP4);
}

QSize QIPEdit::sizeHint() const
{
    return QSize(250, 30);
}

QSize QIPEdit::minimumSizeHint() const
{
    return QSize(50,30);
}

QString QIPEdit::GetIP() const
{
    if(m_lineEditIP1->text().isEmpty() || m_lineEditIP2->text().isEmpty() ||
            m_lineEditIP3->text().isEmpty() || m_lineEditIP4->text().isEmpty())
    {
        return "";
    }
    return m_strIP;
}

bool QIPEdit::eventFilter(QObject *watched, QEvent *event)
{
    QLineEdit* lineEditIP = qobject_cast<QLineEdit*>(watched);
    if(lineEditIP)
    {
        if (event->type() == QEvent::KeyPress)
        {
            QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
            if (keyEvent->key() == Qt::Key_Period)                 //如果当前按下了小数点则移动焦点到下一个输入框
            {
                if(!lineEditIP->text().isEmpty())                  //文本框不为空时后移
                {
                    this->focusNextChild();
                    QLineEdit* lineEditNext = qobject_cast<QLineEdit*>(focusWidget());
                    lineEditNext->selectAll();
                }
            }
            else if (keyEvent->key() == Qt::Key_Backspace && lineEditIP->cursorPosition() == 0 )    //如果当前按下了小数点则移动焦点到下一个输入框
            {

                if(lineEditIP != m_lineEditIP1 && focusNextPrevChild(false))
                {
                    QLineEdit* lineEditPrev = qobject_cast<QLineEdit*>(focusWidget());
                    lineEditPrev->setCursorPosition(lineEditPrev->text().size());
                    lineEditPrev->backspace();
                }
            }
            else if(keyEvent->key() == Qt::Key_Left && lineEditIP->cursorPosition() == 0)
            {                
                if(lineEditIP != m_lineEditIP1 && focusNextPrevChild(false))
                {
                    QLineEdit* lineEditPrev = qobject_cast<QLineEdit*>(focusWidget());
                    lineEditPrev->setCursorPosition(lineEditPrev->text().size());

                }
            }
            else if(keyEvent->key() == Qt::Key_Right && lineEditIP->cursorPosition() == lineEditIP->text().size())
            {
                if(lineEditIP != m_lineEditIP4 && focusNextPrevChild(true))
                {
                    QLineEdit* lineEditNext = qobject_cast<QLineEdit*>(focusWidget());
                    lineEditNext->setCursorPosition(0);
                }
                return false;
            }
            else if (keyEvent->matches(QKeySequence::Paste))
            {
                QClipboard* clipBoard = QApplication::clipboard();
                QString strIP = clipBoard->text();
                setIP(strIP);
                return  false;
            }
        }
        else if (event->type() == QEvent::InputMethod)
        {
            QInputMethodEvent* inputMethodEvent = static_cast<QInputMethodEvent*>(event);
            QString strText = inputMethodEvent->commitString();
            QString strText2 = inputMethodEvent->preeditString();
            qDebug()<<strText << "11111" << strText2;
            if(strText.contains("。") && !lineEditIP->text().isEmpty())
            {
                this->focusNextChild();
                QLineEdit* lineEditNext = qobject_cast<QLineEdit*>(focusWidget());
                lineEditNext->selectAll();
            }
        }
    }
    return QWidget::eventFilter(watched, event);
}

void QIPEdit::clear()
{
    m_lineEditIP1->clear();
    m_lineEditIP2->clear();
    m_lineEditIP3->clear();
    m_lineEditIP4->clear();
    m_lineEditIP1->setFocus();
}

bool QIPEdit::setIP(const QString &strIP)
{
    //先检测IP地址是否合法
    QRegExp regExp("((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)");
    if (!regExp.exactMatch(strIP))
    {
        return false;
    }

    if (strIP != m_strIP)
    {
        m_strIP = strIP;
        //将IP地址填入各个网段
        QStringList list = m_strIP.split(".");
        m_lineEditIP1->setText(list.at(0));
        m_lineEditIP2->setText(list.at(1));
        m_lineEditIP3->setText(list.at(2));
        m_lineEditIP4->setText(list.at(3));
        m_lineEditIP4->setFocus();
        m_lineEditIP4->setCursorPosition(m_lineEditIP4->text().size());
    }
    return true;
}

void QIPEdit::setBgColor(const QString &bgColor)
{
    if(m_bgColor != bgColor)
    {
        m_bgColor = bgColor;
        setQss();
    }
}

void QIPEdit::setBorderColor(const QString &borderColor)
{
    if(m_borderColor != borderColor)
    {
        m_borderColor = borderColor;
        setQss();
    }
}

void QIPEdit::setBorderRadius(int borderRadius)
{
    if(m_borderRadius != borderRadius)
    {
        m_borderRadius = borderRadius;
        setQss();
    }
}

void QIPEdit::setQss()
{
    QStringList qss;
    qss.append(QString("QFrame#frameIP{border:1px solid %1;border-radius:%2px;}").arg(m_borderColor).arg(m_borderRadius));
    qss.append(QString("QLabel{min-width:15px;background-color:%1;}").arg(m_bgColor));
    qss.append(QString("QLineEdit{background-color:%1;border:none;}").arg(m_bgColor));
    qss.append(QString("QLineEdit#lineEditIP1{border-top-left-radius:%1px;border-bottom-left-radius:%1px;}").arg(m_borderRadius));
    qss.append(QString("QLineEdit#lineEditIP4{border-top-right-radius:%1px;border-bottom-right-radius:%1px;}").arg(m_borderRadius));
    setStyleSheet(qss.join(""));
}

void QIPEdit::textChanged(const QString &text)
{
    int len = text.length();
    int value = text.toInt();
    if (len == 3)
    {
        if (value >= 100 && value <= 255)
        {
            this->focusNextChild();
        }
    }

    m_strIP = QString("%1.%2.%3.%4").arg(m_lineEditIP1->text().toInt()).arg(m_lineEditIP2->text().toInt()).
              arg(m_lineEditIP3->text().toInt()).arg(m_lineEditIP4->text().toInt());
    qDebug()<<"IP:"<<m_strIP;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值