QT IP输入框的实现

QT没有提供完整的IP输入框,如果只用正则表达式和LineEdit不可能实现像Windows下那样的IP输入框。于是我便在网上百度到可以使用四个LineEdit和三个Label可以实现像Windows下那样的IP输入框。网上的几乎都是一个界面中只有IP的输入框,可是由于项目要求我的一个界面不可能只有IP输入框。于是便花了我差不多快一个星期的时间(花的时间有点长)终于实现了我想要的效果。

流程图:
在这里插入图片描述

我首先在xx.ui界面中画了四个LineEdit(分别取名为(le_ip_1,le_ip_2,le_ip_3,le_ip_4)做输入IP地址用,限定了最大输入长度为3)三个Label(输入点)最外面的框是一个容器Frame
在这里插入图片描述
代码:
xx.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QRegExp>
#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    
   //设置lineEdit的边框隐藏
    
    ui->le_ip_1->setFrame(false);
    ui->le_ip_2->setFrame(false);
    ui->le_ip_3->setFrame(false);
    ui->le_ip_4->setFrame(false);
    
    //安装事件过滤器
    ui->le_ip_1->installEventFilter(this);
    ui->le_ip_2->installEventFilter(this);
    ui->le_ip_3->installEventFilter(this);
    ui->le_ip_4->installEventFilter(this);
    
//正则表达式,为了实现每输入两个字节如果错误就能提示

    QRegExp rx ( "^([0-9]{1,3})$" );
    QValidator *validator = new QRegExpValidator(rx, this);
    ui->le_ip_1->setValidator( validator );
    ui->le_ip_2->setValidator( validator);
    ui->le_ip_3->setValidator( validator);
    ui->le_ip_4->setValidator( validator );

    connect( this, SIGNAL(signalTextChanged(QLineEdit*)),this,  SLOT(slotTextChanged(QLineEdit*)),Qt::QueuedConnection );
    
    connect(ui->le_ip_1,SIGNAL(textChanged(QString)),this,SLOT(lineEditChanged()));
    connect(ui->le_ip_2,SIGNAL(textChanged(QString)),this,SLOT(lineEditChanged()));
    connect(ui->le_ip_3,SIGNAL(textChanged(QString)),this,SLOT(lineEditChanged()));
    connect(ui->le_ip_4,SIGNAL(textChanged(QString)),this,SLOT(lineEditChanged()));
}
void MainWindow::lineEditChanged()
{
//为了判断是哪个LineEdit发出信号
    QLineEdit *pEdit = qobject_cast<QLineEdit *>(sender());

    if(pEdit->text().size() == 3 && pEdit->text().size() == pEdit->cursorPosition())
    {

       moveNextLine(pdit);
    }
}

void MainWindow::slotTextChanged(QLineEdit *pEdit)
{
    if(pEdit->text().size() == 3 && pEdit->text().size() == pEdit->cursorPosition())
    {
     moveNextLine(pdit);
    }
}


bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{

    bool bRes = QWidget::eventFilter(obj,event);
    if(obj == ui->le_ip_1 || obj == ui->le_ip_2 || obj == ui->le_ip_3 || obj == ui->le_ip_4)
    {

        if(event->type() == QEvent::KeyPress)
        {

            QKeyEvent * pEvent = dynamic_cast<QKeyEvent *>(event);
            
            QLineEdit* pdit = qobject_cast<QLineEdit*>(obj);

            if(pdit == ui->le_ip_1||pdit == ui->le_ip_2||pdit == ui->le_ip_3 || pdit == ui->le_ip_4)
            {
                switch(pEvent->key())
                {

                case Qt::Key_Left:
                    if(pdit->cursorPosition()==0)
                    {

                       movePreLine( pdit);

                    }
                    break;
                case Qt::Key_Right:
                    if(pdit->text().isEmpty()||(pdit->text().size() == pdit->cursorPosition()))
                    {
                       moveNextLine(pdit);
                    }
                    break;
                case Qt::Key_0:
                    if(pdit->text().isEmpty()||pdit->text() == "0")
                    {
                        pdit->setText("000");

                       moveNextLine(pdit);
                    }
                    emit signalTextChanged(pdit);
                    break;
                case::Qt::Key_Backspace:
                    if(pdit->text().isEmpty()||pdit->cursorPosition() == 0)
                    {

                         movePreLine( pdit);

                    }
                    break;
                case Qt::Key_Comma:
                case Qt::Key_Period:
                        moveNextLine(pdit);
                    break;
               default:
                    emit signalTextChanged(pdit);
                    break;
                }
            }
        }
    }
    return bRes;
}

void  MainWindow:: moveNextLine(QLineEdit * pdit)
{
    if(pdit != ui->le_ip_4)
    {
        if(pdit == ui->le_ip_1)
        {
            ui->le_ip_2->setFocus();
            ui->le_ip_2->selectAll();
            ui->le_ip_2->setCursorPosition(0);
        }
        else if(pdit == ui->le_ip_2)
        {
            ui->le_ip_3->setFocus();
            ui->le_ip_3->selectAll();
            ui->le_ip_3->setCursorPosition(0);
        }
        else if(pdit ==ui->le_ip_3)
        {
            ui->le_ip_4->setFocus();
            ui->le_ip_4->selectAll();
            ui->le_ip_4->setCursorPosition(0);
        }
    }
}
void MainWindow::movePreLine(QLineEdit * pdit)
{

    if(pdit != ui->le_ip_1)
    {
        if(pdit == ui->le_ip_2)
        {
            ui->le_ip_1->setFocus();
            ui->le_ip_1->setCursorPosition(ui->le_ip_1->text().size());
        }
        else if(pdit == ui->le_ip_3)
        {

            ui->le_ip_2->setFocus();
            ui->le_ip_2->setCursorPosition(ui->le_ip_2->text().size());
        }
        else if(pdit ==ui->le_ip_4)
        {
            ui->le_ip_3->setFocus();
            ui->le_ip_3->setCursorPosition(ui->le_ip_3->text().size());
        }
    }
}


void MainWindow::on_le_ip_1_editingFinished()
{
    QString ipaddr = ui->le_ip_1->text();
    int ipnum;
    ipnum = ipaddr.toInt();

    if(ipnum == 127)
    {
        ui->le_ip_1->setText("1");
        QMessageBox::warning(this,tr("warning"),tr("以127开头的是无效地址,为环回地址,请输入1~223之间的其他数"));
    }

    if(ipnum >223)
    {
        ui->le_ip_1->setText("223");
        QMessageBox::warning(this,tr("warning"),tr("请输入1~223之间的数"));
    }
}

void MainWindow::on_le_ip_2_editingFinished()
{
    QString ipaddr = ui->le_ip_2->text();
    int ipnum;
    ipnum = ipaddr.toInt();
    if(ipnum >255)
    {
        ui->le_ip_2->setText("255");
        QMessageBox::warning(this,tr("warning"),tr("请输入0~255之间的数"));
    }
}

void MainWindow::on_le_ip_3_editingFinished()
{
    QString ipaddr = ui->le_ip_3->text();
    int ipnum;
    ipnum = ipaddr.toInt();
    if(ipnum >255)
    {
        ui->le_ip_3->setText("255");
        QMessageBox::warning(this,tr("warning"),tr("请输入0~255之间的数"));
    }
}

xx.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "ui_mainwindow.h"
#include <QMainWindow>
#include <QWidget>
#include <QLabel>
#include <QLineEdit>
#include <QKeyEvent>
#include <QIntValidator>

#define MAX  100

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    
    void            movePreLine(QLineEdit* pdit);
    void            moveNextLine(QLineEdit* pdit);
    virtual bool eventFilter(QObject *obj, QEvent *event);
    
public slots:
     void slotTextChanged(QLineEdit *pEdit);
     void lineEditChanged();


signals:
     void signalTextChanged(QLineEdit *pEdit);

private slots:
     void on_le_ip_1_editingFinished();

     void on_le_ip_2_editingFinished();

     void on_le_ip_3_editingFinished();

     void on_le_ip_4_editingFinished();

     void on_le_ip_4_returnPressed();

     void on_le_ip_4_textEdited();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

参考博客:https://blog.csdn.net/ganggegel/article/details/78644919?utm_source=app
https://blog.csdn.net/u013625961/article/details/76854559?utm_source=app
遇到的问题:

1.不同框之间焦点的跳转
由于我百度到的都是将几个LineEdit都是将它们加到一个指针数组或者将LineEdit提升为一个类,而我的几个LineEdit是在ui界面中画好的,如果提升为一个类,可我的界面中不可能只有IP输入框,所以将会很麻烦,我也想过将它们加到指针数组中,可打印出的地址是同一个,老是不对,后来百度到原来在ui界面中画好的不能将它们加到指针数组中。

解决方法:只能采取笨办法判断是哪个lineedit发出信号再做相应的操作,虽然实现了相应的功能,但代码有点冗余,有待改进。

2.正则表达式模块
我想实现的是每输入两个字节如果出错就能够弹出提示框输入出错,可如果采用以下代码,它只是对你的输入做出了限制,出错了只会不显示在编辑框中。

QRegExp rx ( "^(0|[1-9]|[1-9][0-9]|1[0-9][0-9]|2([0-4][0-9]|5[0-5]))$" );
        QValidator *validator = new QRegExpValidator(rx, pEdit);
        pEdit->setValidator( validator );

解决方法:将rx中的限制改为( "^([0-9]{1,3})$" );然后再在每个输入框编辑完成时对其中的文本进行判断是否合法

3.事件过滤器模块
由于我前面没有使用指针数组或将lineedit提升为一个类,所以我不能直接得到ui界面中对象,只能得到对象名。

解决方法:
QLineEdit* pdit = qobject_cast<QLineEdit*>(obj);
这时就可以根据pdit来判断是ui界面中的哪个对象

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值