Qt writing custom control-IP address input box

I. Introduction

This IP address input box control is probably badly written. A random search on the Internet will turn up a lot of it. It is probably because this control is too easy and is very suitable for novices to practice. The general idea is to use 4 qlineedit controls to put them together, and then Each input box is set up with regular expression filtering to allow only 3 digits to be entered, and then an event filter is installed to recognize the carriage return and automatically jump to the next input box. Regarding how to set up regular expression filtering, you can search for this. I don’t understand this rule very well. It seems that there are special books dedicated to regular expressions. This may be very powerful.

Open source address: https://gitee.com/feiyangqingyun/QWidgetDemo https://github.com/feiyangqingyun/QWidgetDemo

2. Functions implemented

  • 1: IP address can be set and the box will be filled in automatically
  • 2: IP address can be cleared
  • 3: Support automatic switching by pressing the small dot
  • 4: Support automatic switching of backspace key
  • 5:Support IP address filtering
  • 6: Background color/border color/border fillet angle can be set

3. Effect drawing

4. Header file code

#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


As a benefit for this article, you can receive a Qt development learning package and technical videos for free, including (C++ language basics, introduction to Qt programming, QT signal and slot mechanism, QT interface development-image drawing, QT network, QT database programming, QT project practice , QT embedded development, Quick module, etc.) ↓↓↓↓↓↓See below↓↓Click at the bottom of the article to receive the fee↓↓

5. Core code

#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-width: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;
    }
}


6. Control introduction

  1. More than 160 exquisite controls, covering various dashboards, progress bars, progress balls, compasses, curves, rulers, thermometers, navigation bars, navigation bars, flatui, highlight buttons, sliding selectors, lunar calendar, etc. Far exceeds the number of controls integrated by qwt.
  2. Each class can be independently formed into a separate control, with zero coupling. Each control has a header file and an implementation file, and does not rely on other files. It is convenient for a single control to be integrated into the project in the form of source code, with less code. The control classes of qwt are interlocking and highly coupled. If you want to use one of the controls, you must include all the code.
  3. All written in pure Qt, drawn by QWidget+QPainter, supports any Qt version from Qt4.6 to Qt5.13, supports compilers such as mingw, msvc, gcc, etc., and supports any operating system such as windows+linux+mac+embedded linux, etc., without garbled code , can be directly integrated into Qt Creator and used like the built-in controls. Most effects only need to set a few properties, which is extremely convenient.
  4. Each control has a corresponding separate DEMO containing the source code of the control for easy reference and use. It also provides an integrated DEMO used by all controls.
  5. The source code of each control has detailed Chinese comments and is written in accordance with unified design specifications, making it easy to learn how to write custom controls.
  6. The default color matching of each control and the color matching corresponding to the demo are very exquisite.
  7. More than 130 visible controls and 6 invisible controls.
  8. Some controls provide multiple style choices and multiple indicator style choices.
  9. All controls adapt to form stretch changes.
  10. Integrated custom control attribute designer, supports drag and drop design, WYSIWYG, supports import and export of xml format.
  11. Comes with activex control demo, all controls can be run directly in the IE browser.
  12. Integrate fontawesome graphic fonts + hundreds of graphic fonts collected by Alibaba iconfont, and enjoy the fun brought by graphic fonts.
  13. All controls finally generate a dynamic library file (dll or so, etc.), which can be directly integrated into qtcreator for drag and drop design.
  14. There is already a qml version, and a pyqt version will be considered later if there is great demand from users.
  15. The custom control plug-in is open to dynamic library use (free forever), without any backdoors or restrictions, so please feel free to use it.
  16. Currently, 32 versions of dll have been provided, among which the version qt_5_7_0_mingw530_32 will always be guaranteed to be the latest and complete.
  17. Controls are added and improved from time to time, and the SDK is updated from time to time. Suggestions are welcome, thank you!
  18. For introductory Qt books, we recommend Huo Yafei's "Quick Start with Qt Creator" and "Introduction to Qt5 Programming". For advanced Qt books, we recommend the official "C++ GUI Qt4 Programming".
  19. I highly recommend the series of self-cultivation and planning books for programmers, "The Big Talk Programmer", "Programmer's Growth Course", and "The Worry-Relieving Programmer", which will benefit you a lot and will last a lifetime!
  20. SDK address: https://gitee.com/feiyangqingyun/QUCSDK https://github.com/feiyangqingyun/qucsdk

Original link: https://www.cnblogs.com/feiyangqingyun/p/11665022.html

As a benefit for this article, you can receive a Qt development learning package and technical videos for free, including (C++ language basics, introduction to Qt programming, QT signal and slot mechanism, QT interface development-image drawing, QT network, QT database programming, QT project practice , QT embedded development, Quick module, etc.) ↓↓↓↓↓↓See below↓↓Click at the bottom of the article to receive the fee↓↓

Guess you like

Origin blog.csdn.net/hw5230/article/details/132864591