zoukankan      html  css  js  c++  java
  • Qt编写自定义控件68-IP地址输入框

    一、前言

    这个IP地址输入框控件,估计写烂了,网上随便一搜索,保证一大堆,估计也是因为这个控件太容易了,非常适合新手练手,一般的思路都是用4个qlineedit控件拼起来,然后每个输入框设置正则表达式过滤只能输入3位数字,然后安装事件过滤器识别回车自动跳到下一个输入框。关于如何设置正则表达式过滤,这个可以搜索查到,本人也不大懂这个规则,貌似还有专门的书籍专门介绍正则表达式,可能这块非常强大。

    开源地址:https://gitee.com/feiyangqingyun/QWidgetDemo https://github.com/feiyangqingyun/QWidgetDemo

    二、实现的功能

    • 1:可设置IP地址,自动填入框
    • 2:可清空IP地址
    • 3:支持按下小圆点自动切换
    • 4:支持退格键自动切换
    • 5:支持IP地址过滤
    • 6:可设置背景色/边框颜色/边框圆角角度

    三、效果图

    四、头文件代码

    #ifndef IPADDRESS_H
    #define IPADDRESS_H
    
    /**
     * IP地址输入框控件 作者:feiyangqingyun(QQ:517216493) 2017-8-11
     * 1:可设置IP地址,自动填入框
     * 2:可清空IP地址
     * 3:支持按下小圆点自动切换
     * 4:支持退格键自动切换
     * 5:支持IP地址过滤
     * 6:可设置背景色/边框颜色/边框圆角角度
     */
    
    #include <QWidget>
    
    class QLabel;
    class QLineEdit;
    
    #ifdef quc
    #if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
    #include <QtDesigner/QDesignerExportWidget>
    #else
    #include <QtUiPlugin/QDesignerExportWidget>
    #endif
    
    class QDESIGNER_WIDGET_EXPORT IPAddress : public QWidget
    #else
    class IPAddress : public QWidget
    #endif
    
    {
        Q_OBJECT
        Q_PROPERTY(QString ip READ getIP WRITE setIP)
    
    public:
        explicit IPAddress(QWidget *parent = 0);
    
    protected:
        bool eventFilter(QObject *watched, QEvent *event);
    
    private:
        QLabel *labDot1;    //第一个小圆点
        QLabel *labDot2;    //第二个小圆点
        QLabel *labDot3;    //第三个小圆点
    
        QLineEdit *txtIP1;  //IP地址网段输入框1
        QLineEdit *txtIP2;  //IP地址网段输入框2
        QLineEdit *txtIP3;  //IP地址网段输入框3
        QLineEdit *txtIP4;  //IP地址网段输入框4
    
        QString ip;         //IP地址
        QString bgColor;    //背景颜色
        QString borderColor;//边框颜色
        int borderRadius;   //边框圆角角度
    
    private slots:
        void textChanged(const QString &text);
    
    public:
        //获取IP地址
        QString getIP()                 const;
    
        QSize sizeHint()                const;
        QSize minimumSizeHint()         const;
    
    public Q_SLOTS:
        //设置IP地址
        void setIP(const QString &ip);
        //清空
        void clear();
    
        //设置背景颜色
        void setBgColor(const QString &bgColor);
        //设置边框颜色
        void setBorderColor(const QString &borderColor);
        //设置边框圆角角度
        void setBorderRadius(int borderRadius);
    
    };
    
    #endif // IPADDRESS_H
    
    
    

    五、核心代码

    #pragma execution_character_set("utf-8")
    
    #include "ipaddress.h"
    #include "qlabel.h"
    #include "qlineedit.h"
    #include "qboxlayout.h"
    #include "qregexp.h"
    #include "qvalidator.h"
    #include "qevent.h"
    #include "qdebug.h"
    
    IPAddress::IPAddress(QWidget *parent) : QWidget(parent)
    {
        bgColor = "#FFFFFF";
        borderColor = "#A6B5B8";
        borderRadius = 3;
    
        //用于显示小圆点的标签,居中对齐
        labDot1 = new QLabel;
        labDot1->setAlignment(Qt::AlignCenter);
        labDot1->setText(".");
    
        labDot2 = new QLabel;
        labDot2->setAlignment(Qt::AlignCenter);
        labDot2->setText(".");
    
        labDot3 = new QLabel;
        labDot3->setAlignment(Qt::AlignCenter);
        labDot3->setText(".");
    
        //用于输入IP地址的文本框,居中对齐
        txtIP1 = new QLineEdit;
        txtIP1->setObjectName("txtIP1");
        txtIP1->setAlignment(Qt::AlignCenter);
        txtIP1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
        connect(txtIP1, SIGNAL(textChanged(QString)), this, SLOT(textChanged(QString)));
    
        txtIP2 = new QLineEdit;
        txtIP2->setObjectName("txtIP2");
        txtIP2->setAlignment(Qt::AlignCenter);
        txtIP2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
        connect(txtIP2, SIGNAL(textChanged(QString)), this, SLOT(textChanged(QString)));
    
        txtIP3 = new QLineEdit;
        txtIP3->setObjectName("txtIP3");
        txtIP3->setAlignment(Qt::AlignCenter);
        txtIP3->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
        connect(txtIP3, SIGNAL(textChanged(QString)), this, SLOT(textChanged(QString)));
    
        txtIP4 = new QLineEdit;
        txtIP4->setObjectName("txtIP4");
        txtIP4->setAlignment(Qt::AlignCenter);
        txtIP4->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
        connect(txtIP4, SIGNAL(textChanged(QString)), this, SLOT(textChanged(QString)));
    
        //设置IP地址校验过滤
        QRegExp regExp("(2[0-5]{2}|2[0-4][0-9]|1?[0-9]{1,2})");
        QRegExpValidator *validator = new QRegExpValidator(regExp, this);
        txtIP1->setValidator(validator);
        txtIP2->setValidator(validator);
        txtIP3->setValidator(validator);
        txtIP4->setValidator(validator);
    
        //绑定事件过滤器,识别键盘按下
        txtIP1->installEventFilter(this);
        txtIP2->installEventFilter(this);
        txtIP3->installEventFilter(this);
        txtIP4->installEventFilter(this);
    
        QFrame *frame = new QFrame;
        frame->setObjectName("frameIP");
    
        QStringList qss;
        qss.append(QString("QFrame#frameIP{border:1px solid %1;border-radius:%2px;}").arg(borderColor).arg(borderRadius));
        qss.append(QString("QLabel{min-15px;background-color:%1;}").arg(bgColor));
        qss.append(QString("QLineEdit{background-color:%1;border:none;}").arg(bgColor));
        qss.append(QString("QLineEdit#txtIP1{border-top-left-radius:%1px;border-bottom-left-radius:%1px;}").arg(borderRadius));
        qss.append(QString("QLineEdit#txtIP4{border-top-right-radius:%1px;border-bottom-right-radius:%1px;}").arg(borderRadius));
        frame->setStyleSheet(qss.join(""));
    
        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(txtIP1);
        layout->addWidget(labDot1);
        layout->addWidget(txtIP2);
        layout->addWidget(labDot2);
        layout->addWidget(txtIP3);
        layout->addWidget(labDot3);
        layout->addWidget(txtIP4);
    }
    
    bool IPAddress::eventFilter(QObject *watched, QEvent *event)
    {
        if (event->type() == QEvent::KeyPress) {
            QLineEdit *txt = (QLineEdit *)watched;
            if (txt == txtIP1 || txt == txtIP2 || txt == txtIP3 || txt == txtIP4) {
                QKeyEvent *key = (QKeyEvent *)event;
    
                //如果当前按下了小数点则移动焦点到下一个输入框
                if (key->text() == ".") {
                    this->focusNextChild();
                }
    
                //如果按下了退格键并且当前文本框已经没有了内容则焦点往前移
                if (key->key() == Qt::Key_Backspace) {
                    if (txt->text().length() <= 1) {
                        this->focusNextPrevChild(false);
                    }
                }
            }
        }
    
        return QWidget::eventFilter(watched, event);
    }
    
    void IPAddress::textChanged(const QString &text)
    {
        int len = text.length();
        int value = text.toInt();
    
        //判断当前是否输入完成一个网段,是的话则自动移动到下一个输入框
        if (len == 3) {
            if (value >= 100 && value <= 255) {
                this->focusNextChild();
            }
        }
    
        //拼接成完整IP地址
        ip = QString("%1.%2.%3.%4").arg(txtIP1->text()).arg(txtIP2->text()).arg(txtIP3->text()).arg(txtIP4->text());
    }
    
    QString IPAddress::getIP() const
    {
        return this->ip;
    }
    
    QSize IPAddress::sizeHint() const
    {
        return QSize(250, 20);
    }
    
    QSize IPAddress::minimumSizeHint() const
    {
        return QSize(30, 10);
    }
    
    void IPAddress::setIP(const QString &ip)
    {
        //先检测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(ip)) {
            return;
        }
    
        if (this->ip != ip) {
            this->ip = ip;
    
            //将IP地址填入各个网段
            QStringList list = ip.split(".");
            txtIP1->setText(list.at(0));
            txtIP2->setText(list.at(1));
            txtIP3->setText(list.at(2));
            txtIP4->setText(list.at(3));
        }
    }
    
    void IPAddress::clear()
    {
        txtIP1->clear();
        txtIP2->clear();
        txtIP3->clear();
        txtIP4->clear();
        txtIP1->setFocus();
    }
    
    void IPAddress::setBgColor(const QString &bgColor)
    {
        if (this->bgColor != bgColor) {
            this->bgColor = bgColor;
        }
    }
    
    void IPAddress::setBorderColor(const QString &borderColor)
    {
        if (this->borderColor != borderColor) {
            this->borderColor = borderColor;
        }
    }
    
    void IPAddress::setBorderRadius(int borderRadius)
    {
        if (this->borderRadius != borderRadius) {
            this->borderRadius = borderRadius;
        }
    }
    
    
    

    六、控件介绍

    1. 超过160个精美控件,涵盖了各种仪表盘、进度条、进度球、指南针、曲线图、标尺、温度计、导航条、导航栏,flatui、高亮按钮、滑动选择器、农历等。远超qwt集成的控件数量。
    2. 每个类都可以独立成一个单独的控件,零耦合,每个控件一个头文件和一个实现文件,不依赖其他文件,方便单个控件以源码形式集成到项目中,较少代码量。qwt的控件类环环相扣,高度耦合,想要使用其中一个控件,必须包含所有的代码。
    3. 全部纯Qt编写,QWidget+QPainter绘制,支持Qt4.6到Qt5.13的任何Qt版本,支持mingw、msvc、gcc等编译器,支持任意操作系统比如windows+linux+mac+嵌入式linux等,不乱码,可直接集成到Qt Creator中,和自带的控件一样使用,大部分效果只要设置几个属性即可,极为方便。
    4. 每个控件都有一个对应的单独的包含该控件源码的DEMO,方便参考使用。同时还提供一个所有控件使用的集成的DEMO。
    5. 每个控件的源代码都有详细中文注释,都按照统一设计规范编写,方便学习自定义控件的编写。
    6. 每个控件默认配色和demo对应的配色都非常精美。
    7. 超过130个可见控件,6个不可见控件。
    8. 部分控件提供多种样式风格选择,多种指示器样式选择。
    9. 所有控件自适应窗体拉伸变化。
    10. 集成自定义控件属性设计器,支持拖曳设计,所见即所得,支持导入导出xml格式。
    11. 自带activex控件demo,所有控件可以直接运行在ie浏览器中。
    12. 集成fontawesome图形字体+阿里巴巴iconfont收藏的几百个图形字体,享受图形字体带来的乐趣。
    13. 所有控件最后生成一个动态库文件(dll或者so等),可以直接集成到qtcreator中拖曳设计使用。
    14. 目前已经有qml版本,后期会考虑出pyqt版本,如果用户需求量很大的话。
    15. 自定义控件插件开放动态库使用(永久免费),无任何后门和限制,请放心使用。
    16. 目前已提供32个版本的dll,其中qt_5_7_0_mingw530_32这个版本会一直保证最新的完整的。
    17. 不定期增加控件和完善控件,不定期更新SDK,欢迎各位提出建议,谢谢!
    18. Qt入门书籍推荐霍亚飞的《Qt Creator快速入门》《Qt5编程入门》,Qt进阶书籍推荐官方的《C++ GUI Qt4编程》。
    19. 强烈推荐程序员自我修养和规划系列书《大话程序员》《程序员的成长课》《解忧程序员》,受益匪浅,受益终生!
    20. SDK地址:https://gitee.com/feiyangqingyun/QUCSDK https://github.com/feiyangqingyun/qucsdk
  • 相关阅读:
    爬取豆瓣电影信息
    MongoDB的聚合操作以及与Python的交互
    matplotlib简单示例
    MongoDB基本操作
    K近邻算法
    Scrapy爬取博客园精华区内容
    爬虫失败
    Markdown基本使用方法
    UITableViewCell高度自适应变化
    KVO和NSNotification
  • 原文地址:https://www.cnblogs.com/feiyangqingyun/p/11665022.html
Copyright © 2011-2022 走看看