Qt控件-自定义IP地址控件

文章目录

  • 一、IP 地址及其分类原则
    • 1、IP地址
    • 2、IP的分类原则
      • A类地址
      • B类地址
      • C类地址
      • D类地址
      • E类地址
  • 二、IP地址的正则表达式
  • 三、自定义控件IPLineEdit
    • 1.IPLineEdit 核心
    • 2.eventFilter 事件过滤器


一、IP 地址及其分类原则

1、IP地址

现在的IP网络使用32位地址,以点分十进制表示,如192.168.0.1。地址格式为:IP地址=网络地址+主机地址 或 IP地址=主机地址+子网地址+主机地址。网络地址是由Internet权力机构(InterNIC)统一分配的,目的是为了保证网络地址的全球唯一性。主机地址是由各个网络的系统管理员分配。网络地址的唯一性与网络内主机地址的唯一性确保了IP地址的全球唯一性

2、IP的分类原则

网络号:用于识别主机所在的网络;主机号:用于识别该网络中的主机。IP 地址分为五类:

A类地址

A 类保留给政府机构:
(1) A 类地址第1字节为网络地址,其它3个字节为主机地址。
(2) A 类地址范围:1.0.0.1—126.255.255.254
(3) A 类地址中的私有地址和保留地址:
① 10.X.X.X 是私有地址(所谓的私有地址就是在互联网上不使用,而被用在局域网络中的地址)。范围(10.0.0.0-10.255.255.255)
② 127.X.X.X 是保留地址,用做循环测试用的。

B类地址

B 类分配给中等规模的公司:
(1) B 类地址第1字节和第2字节为网络地址,其它2个字节为主机地址。
(2) B 类地址范围:128.0.0.1—191.255.255.254。
(3) B 类地址的私有地址和保留地址
① 172.16.0.0—172.31.255.255 是私有地址
② 169.254.X.X 是保留地址。如果你的IP地址是自动获取IP地址,而你在网络上又没有找到可用的DHCP服务器。就会得到其中一个IP。

C类地址

C 类分配普通用户:
(1) C 类地址第1字节、第2字节和第3个字节为网络地址,第4个个字节为主机地址。另
外第1个字节的前三位固定为110。
(2) C 类地址范围:192.0.0.1—223.255.255.254。
(3) C 类地址中的私有地址:
192.168.X.X 是私有地址。(192.168.0.0-192.168.255.255)

D类地址

多目的广播地址:
(1) D 类地址不分网络地址和主机地址,它的第1个字节的前四位固定为1110。
(2) D 类地址范围:224.0.0.1—239.255.255.254

E类地址

实验地址或将来使用:
(1) E 类地址不分网络地址和主机地址,它的第1个字节的前五位固定为11110。
(2) E 类地址范围:240.0.0.1—255.255.255.254


二、IP地址的正则表达式

正则表达式([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])用于匹配 0 到 255 之间的整数,用于验证 IP 地址的每个数字段(如 192.168.1.1 中的每个部分)。

QRegularExpression regExp("([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])");

IP地址的正则表达式由四个部分通过 |(或)分隔,表示只要满足其中一个条件即可匹配:

1、[1-9]?[0-9]
匹配范围:0 到 99。
当 [1-9]? 不出现时(即 0 次):[0-9]:匹配 0-9 的单个数字(如 0、5);
当 [1-9]? 出现时(如 1-9):[0-9]:后面跟 0-9,形成两位数(如 10、99)。
不允许两位数的前导零:例如 01、09 无法匹配,因为 [1-9]? 无法匹配 0。

2、1[0-9]{2}
匹配范围:100 到 199。固定第一位为 1。[0-9]{2}:后两位是任意 0-9 的数字。

3、2[0-4][0-9]
匹配范围:200到249。2为固定第一位,第二位是 0 到 4 的数字;第三位是任意 0 到 9 的数字。

4、25[0-5]
匹配范围:250到255。25为固定前两位,第三位数字为0到5的数字。

该写法禁止前导零,09会被认为非法值无法匹配。

三、自定义控件IPLineEdit

1.IPLineEdit 核心

QT6.0以上的程序把 QRegExp类移动到了core 5compat中了,使用QRegularExpression替代QRegExp,同时QRegExpValidator使用QRegularExpressionValidator替代。#include 、#include
通过正则表达式限制编辑框的输入内容。

IPLineEdit::IPLineEdit(QWidget *parent)
    :QLineEdit(parent)
{
    QHBoxLayout *hboxLayout = new QHBoxLayout(this);
    hboxLayout->setContentsMargins(1,1,1,1);

    QRegularExpression regExp("([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])");

    QLabel *labelDot[3];
    for (int i=0;i<IP_INPUT_SIZE;i++) {
        m_lineEdit[i] = new QLineEdit(this);
        m_lineEdit[i]->setProperty("ip",true);
        //保存线条编辑是否使用边框绘制本身
        m_lineEdit[i]->setFrame(false);

        //输入框最大位数
        m_lineEdit[i]->setMaxLength(3);
        //消除布局中的空隙,居中
        m_lineEdit[i]->setAlignment(Qt::AlignCenter);

        //保存小部件的默认布局
        m_lineEdit[i]->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);

        //添加验证规则
        m_lineEdit[i]->setValidator(new QRegularExpressionValidator(regExp,this));

        //安装事件过滤器, 过滤子控件事件,截获控件按键,鼠标事件
        m_lineEdit[i]->installEventFilter(this);

        hboxLayout->addWidget(m_lineEdit[i]);

        if (i<3) {
            labelDot[i] = new QLabel(this);
            labelDot[i]->setText(".");
            labelDot[i]->setFixedWidth(2);
            hboxLayout->addWidget(labelDot[i]);
        }

        this->setReadOnly(true);

        m_lineEdit[0]->setFocus();
        m_lineEdit[0]->selectAll();
    }
}

2.eventFilter 事件过滤器

实现功能:当输入框中的数字大于3,或者输入.光标自动跳到下一个输入位置;通过键盘控制光标在输入框中位置。

bool IPLineEdit::eventFilter(QObject *obj, QEvent *event)
{
    if (children().contains(obj) && QEvent::KeyPress == event->type()) {

        QKeyEvent *keyEvent = dynamic_cast<QKeyEvent*>(event);
        QLineEdit *pCurrentEdit = qobject_cast<QLineEdit*>(obj);

        switch (keyEvent->key()) {
            case Qt::Key_0:
            case Qt::Key_1:
            case Qt::Key_2:
            case Qt::Key_3:
            case Qt::Key_4:
            case Qt::Key_5:
            case Qt::Key_6:
            case Qt::Key_7:
            case Qt::Key_8:
            case Qt::Key_9:
            {
                QString strText = pCurrentEdit->text();
                if (strText.length() <=3 && strText.toInt()*10 > 255) {
                    int index = getIndex(pCurrentEdit);
                    if (index !=-1 && index !=3) {
                        m_lineEdit[index+1]->setFocus();
                        m_lineEdit[index+1]->selectAll();
                    }
                }
                return QLineEdit::eventFilter(obj, event);
            }
            break;
            case Qt::Key_Left:
            {
                if (!pCurrentEdit->cursorPosition()) {
                    int index = getIndex(pCurrentEdit);
                    if (index != -1 && index !=0) {
                        m_lineEdit[index-1]->setFocus();
                        int length = m_lineEdit[index-1]->text().length();
                        m_lineEdit[index-1]->setCursorPosition(length?length:0);
                    }
                }

                return QLineEdit::eventFilter(obj, event);
            }
            break;
            case Qt::Key_Right:
            {
                if (!pCurrentEdit->cursorPosition()) {
                    int index = getIndex(pCurrentEdit);
                    if (index != -1 && index !=3) {
                        m_lineEdit[index+1]->setFocus();
                        int length = m_lineEdit[index+1]->text().length();
                        m_lineEdit[index+1]->setCursorPosition(length?length:0);
                    }
                }

                return QLineEdit::eventFilter(obj, event);
            }
            break;
            case Qt::Key_Backspace: //后退键
            {
                QString strText = pCurrentEdit->text();
                if (strText.isEmpty()) {
                    int index = getIndex(pCurrentEdit);
                    if (index != -1 && index !=0) {
                        m_lineEdit[index-1]->setFocus();
                        int length = m_lineEdit[index-1]->text().length();
                        m_lineEdit[index-1]->setCursorPosition(length?length:0);
                    }
                }

                return QLineEdit::eventFilter(obj, event);
            }
            break;
            case Qt::Key_Period: //就是一个点号(.)
            {
                int index = getIndex(pCurrentEdit);
                if (index != -1 && index !=3) {
                    m_lineEdit[index+1]->setFocus();
                    m_lineEdit[index+1]->selectAll();
                }

                return QLineEdit::eventFilter(obj, event);
            }
            break;
        }
    }
}

你可能感兴趣的:(Qt,qt,tcp/ip,php)