查看完整版本: [-- IP地址·输入控件 --]

QTCN开发网 -> Qt代码秀 -> IP地址·输入控件 [打印本页] 登录 -> 注册 -> 回复主题 -> 发表主题

xiaoke123 2020-07-01 11:39

IP地址·输入控件

由于用刘总的IP设置背景和边框圆角不生效,又想区别当前焦点状态,故改了一个
IP控件QIPLineEdit部分功能参考刘总和网上一些代码,实现还是有区别,具体功能如下:
IP地址输入框控件
1:可设置IP地址,自动填入框
2:可清空IP地址
3:支持按下小圆点自动切换
4:支持退格键自动切换
5:支持IP地址过滤
6:可设置/边框颜色/边框圆角角度
7.支持焦点切换高亮不同边框颜色
效果可看如下动态图
[attachment=21715]
真实应用效果,遥控器切焦点
[attachment=21717]

关键代码在:paintEvent 和 eventFilter
h头文件
  1. /************************************************************************/
    /* Modified by:xiaoke
       QQ:1035144170
    */
    /************************************************************************/
    #ifndef QIPLINEEDIT_H
    #define QIPLINEEDIT_H
    #include <QLineEdit>
    #include <QEvent>
    class QIPLineEdit : public QLineEdit
    {
        Q_OBJECT
    public:
        QIPLineEdit(QWidget *parent = 0);
        ~QIPLineEdit();
        //设置IP字符
        void setText(const QString &strIP);
        //当前IP字符
        QString text() const;
        //设置焦点边框颜色
        void setFocusBorderColor(const QString &focusColor);
        //设置边框颜色
        void setBorderColor(const QString &borderColor);
        //设置边框圆角角度
        void setBorderRadius(int borderRadius);
        //清空ip字符
        void clear();
        //设置当前焦点
        void setFocus();
    protected:
        void paintEvent(QPaintEvent *event);
        bool eventFilter(QObject *obj, QEvent *ev);

        int getIndex(QLineEdit *pEdit);
        bool isTextValid(const QString &strIP);
    private:
        QLineEdit *m_lineEidt[4];
        QString focusColor; //焦点边框颜色
        QString borderColor;//边框颜色
        int borderRadius;   //边框圆角角度
    };
    #endif // QIPLINEEDIT_H
CPP实现
  1. /************************************************************************/
    /* Modified by:xiaoke
       QQ:1035144170
    */
    /************************************************************************/
    #include "qiplineedit.h"
    #include <QRegExpValidator>
    #include <QPainter>
    #include <QHBoxLayout>
    #include <QKeyEvent>
    #include <QMessageBox>
    #include <QDebug>

    #pragma execution_character_set("utf-8")

    QIPLineEdit::QIPLineEdit(QWidget *parent)
        : QLineEdit(parent)
    {
        focusColor  = "#26282C";
        borderColor = "#26282C";
        borderRadius = 3;
        this->setStyleSheet(QString("QIPLineEdit{border:1px solid %1;border-radius:%2px;}").arg(borderColor).arg(borderRadius));

        QRegExp rx("(2[0-5]{2}|2[0-4][0-9]|1?[0-9]{1,2})");
        QHBoxLayout *pHBox = new QHBoxLayout(this);
        pHBox->setSpacing(10);
        pHBox->setContentsMargins(5, 5, 5, 5);
        for (int i = 0; i < 4; i++)
        {
            m_lineEidt[i] = new QLineEdit(this);
            m_lineEidt[i]->setFrame(false);
            m_lineEidt[i]->setMaxLength(3);
            m_lineEidt[i]->setAlignment(Qt::AlignCenter);
            m_lineEidt[i]->installEventFilter(this);
            m_lineEidt[i]->setValidator(new QRegExpValidator(rx, this));
            m_lineEidt[i]->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
            pHBox->addWidget(m_lineEidt[i]);
        }
        this->setReadOnly(true);
    }

    QIPLineEdit::~QIPLineEdit()
    {

    }

    void QIPLineEdit::paintEvent(QPaintEvent *event)
    {
        __super::paintEvent(event);
        QPainter painter(this);
        QBrush brush;
        brush.setStyle(Qt::BrushStyle::SolidPattern);
        brush.setColor(Qt::black);
        painter.setBrush(brush);

        //qDebug()  << "xiaoke painter";
        int width = 0;
        for (int i = 0; i < 3; i++)
        {
            width += m_lineEidt[i]->width() + (i == 0 ? 7 : 10);//布局的间隔
            painter.drawEllipse(width, height() / 2 - 2, 4, 4);
        }
    }

    int QIPLineEdit::getIndex(QLineEdit *pEdit)
    {
        int index = -1;
        for (int i = 0; i < 4; i++)
        {
            if (pEdit == m_lineEidt[i])
                index = i;
        }
        return index;
    }

    bool QIPLineEdit::eventFilter(QObject *obj, QEvent *ev)
    {
        if (children().contains(obj) && QEvent::KeyPress == ev->type())
        {
            QKeyEvent *keyEvent = dynamic_cast<QKeyEvent *>(ev);
            QLineEdit *pEdit = 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 = pEdit->text();
                if (pEdit->selectedText().length())
                {
                    pEdit->text().replace(pEdit->selectedText(), QChar(keyEvent->key()));
                }
                else if (strText.length() == 3 || strText.length() < 3 && strText.toInt() * 10 > 255)
                {
                    int index = getIndex(pEdit);
                    if (index != -1 && index != 3)
                    {
                        m_lineEidt[index + 1]->setFocus();
                        m_lineEidt[index + 1]->selectAll();
                    }
                }
                else if (strText.length() == 2 && strText.toInt() * 10 < 255)
                {
                    if (Qt::Key_0 == keyEvent->key() && strText.toInt())
                    {
                        pEdit->setText(strText.insert(pEdit->cursorPosition(), QChar(Qt::Key_0)));
                    }
                }
                return __super::eventFilter(obj, ev);
            }
            break;
            case Qt::Key_Period:
            {
                this->focusNextChild();
            }
            break;
            case Qt::Key_Backspace:
            {
                if (pEdit->text().length() <= 1)
                    this->focusNextPrevChild(false);

                QString strText = pEdit->text();
                if (!strText.length() || strText.length() && !pEdit->cursorPosition())
                {
                    int index = getIndex(pEdit);
                    if (index != -1 && index != 0)
                    {
                        m_lineEidt[index - 1]->setFocus();
                        int length = m_lineEidt[index - 1]->text().length();
                        m_lineEidt[index - 1]->setCursorPosition(length ? length : 0);
                    }
                }
                return __super::eventFilter(obj, ev);
            }
            case Qt::Key_Left:
            {
                if (!pEdit->cursorPosition())
                {
                    int index = getIndex(pEdit);
                    if (index != -1 && index != 0)
                    {
                        m_lineEidt[index - 1]->setFocus();
                        int length = m_lineEidt[index - 1]->text().length();
                        m_lineEidt[index - 1]->setCursorPosition(length ? length : 0);
                    }
                }
                return __super::eventFilter(obj, ev);
            }
            case Qt::Key_Right:
            {
                if (pEdit->cursorPosition() == pEdit->text().length())
                {
                    int index = getIndex(pEdit);
                    if (index != -1 && index != 3)
                    {
                        m_lineEidt[index + 1]->setFocus();
                        m_lineEidt[index + 1]->setCursorPosition(0);
                    }
                }
                return __super::eventFilter(obj, ev);
            }
            default:
                break;
            }
        }
        return false;
    }

    void QIPLineEdit::setText(const QString &strIP)
    {
        if (!isTextValid(strIP))
        {
            QMessageBox::warning(this, "Attention", "Your IP Address is Invalid!", QMessageBox::StandardButton::Ok);
            return;
        }
        else
        {
            int i = 0;
            QStringList ipList = strIP.split(".");
            for each (QString ip in ipList)
            {
                m_lineEidt[i]->setText(ip);
                i++;
            }
        }
    }

    bool QIPLineEdit::isTextValid(const QString &strIP)
    {
        QRegExp rx2("\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b");
        if (!rx2.exactMatch(strIP))
            return false;
        return true;
    }

    QString QIPLineEdit::text() const
    {
        QString strIP;
        for (int i = 0; i < 4; i++)
        {
            strIP.append(m_lineEidt[i]->text());
            if(i == 3)
                continue;
            strIP.append(".");
        }
        //qDebug()  << strIP;
        return strIP;
    }

    void QIPLineEdit::clear()
    {
        for (int i = 0; i < 4; i++)
            m_lineEidt[i]->clear();
    }

    void QIPLineEdit::setFocus()
    {
        m_lineEidt[0]->setFocus();
        /*for (int i = 0; i < 4; i++)
        {
            if(m_lineEidt[i]->text().isNull())
                m_lineEidt[i]->setFocus();
            else
            {
                m_lineEidt[i]->setFocus();
            }
        }*/
        if (m_lineEidt[0]->hasFocus() || m_lineEidt[1]->hasFocus() || m_lineEidt[2]->hasFocus() || m_lineEidt[3]->hasFocus())
        {
            this->setStyleSheet(QString("QIPLineEdit{border:2px solid %1;border-radius:%2px;}").arg(focusColor).arg(borderRadius));
        }else
        {
            this->setStyleSheet(QString("QIPLineEdit{border:1px solid %1;border-radius:%2px;}").arg(borderColor).arg(borderRadius));
        }
    }


    void QIPLineEdit::setFocusBorderColor(const QString &focusColor)
    {
        if (this->focusColor != focusColor) {
            this->focusColor = focusColor;
        }
    }

    void QIPLineEdit::setBorderColor(const QString &borderColor)
    {
        if (this->borderColor != borderColor) {
            this->borderColor = borderColor;
        }
    }

    void QIPLineEdit::setBorderRadius(int borderRadius)
    {
        if (this->borderRadius != borderRadius) {
            this->borderRadius = borderRadius;
        }
    }

相关使用方法:
[attachment=21713]
代码后面就不一一列,想看区别之处可下附件看源码吧!如有什么更好的建议和方法,多多交流[attachment=21718]
[attachment=21757]







liudianwu 2020-07-01 12:59
牛逼,原来是小可大佬,   

xiaoke123 2020-07-01 13:08
liudianwu:牛逼,原来是小可大佬, [表情]  [表情]  (2020-07-01 12:59) 

别啊 我算不上 刘大才是啊 那么谦虚干嘛

dxa572862121 2020-07-08 17:23
     伸手党到此一游

cllssg 2021-05-13 17:54
__super::paintEvent(event);编译不过去,是怎么回事?提示__super没有定义。

清风煮酒 2021-11-29 17:18
多谢大佬,小弟学习学习。

zipl1985 2022-07-23 12:12
学习了,

白马 2022-09-20 17:24
cllssg:__super::paintEvent(event);编译不过去,是怎么回事?提示__super没有定义。 (2021-05-13 17:54) 

如果用mingW的编译器 将//    __super::paintEvent(event);替换成 QLineEdit::paintEvent(event);
相应的//            return __super::eventFilter(obj, ev);替换为 return QLineEdit::eventFilter(obj,ev);

和 //        for each (QString ip in ipList)
//        {
//            m_lineEidt->setText(ip);
//            i++;
//        }
        foreach (QString ip , ipList)
        {
            m_lineEidt->setText(ip);
            i++;
        }

梦幻风 2023-06-17 19:05
谢谢!大佬,学习了


查看完整版本: [-- IP地址·输入控件 --] [-- top --]



Powered by phpwind v8.7 Code ©2003-2011 phpwind
Gzip disabled