/* * 此类的封装参考了:博客网址:http://blog.csdn.net/u011417605,并在此基础上进行修改 * 1.连续输入 * 2.连续删除 * 3.任意位置插入 * 4.自适应大小变化 * 5.正则匹配,每个值不大于255.设置IP值时,有正则验证是否是IP格式 * 实现方法:使用一个大的QLineEdit嵌套四个小的QLineEdit,中间的点是使用paintEvent画出来的。操作是使用eventFilter来进行分发实现的 * 修改: * 用QWidget替换原先的__super * 修改构造函数中的正则匹配 * 修改小圆点位置和大小 * 两个QLineEdit之间的空隙,在绘制小圆点之前,把空气用白色背景填充 * 修改样式表加边框 * 当输入类似192时,焦点自动跳转到下一个QLineEdit出 * 修改text()的输出,使输出由原来的1921680127变为192.168.0.127 **/ #include "qiplineedit.h" #include #include #include #include #define SPACE 5 QIPLineEdit::QIPLineEdit(QWidget *parent) : QLineEdit(parent) { QRegExp rx("((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)"); pHBox = new QHBoxLayout(this); pHBox->setSpacing(SPACE); pHBox->setContentsMargins(0, 0, 0, 0); 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); switch (i) { case 0: m_lineEidt[i]->setStyleSheet(QLatin1String( "border:1px solid #536874;\n" "border-left-color: rgb(0, 0, 0);\n" "border-top-color: rgb(0, 0, 0);\n" "border-bottom-color: rgb(0, 0, 0);\n" "border-right: 0px;\n" "border-right-color: rgbl(255, 255, 255,0);" "border-radius:0px")); break; case 1: m_lineEidt[i]->setStyleSheet(QLatin1String( "border:1px solid #536874;\n" "border-left-color: rgb(255, 255, 255);\n" "border-top-color: rgb(0, 0, 0);\n" "border-bottom-color: rgb(0, 0, 0);\n" "border-right: 0px;\n" "border-left: 0px;\n" "border-right-color: rgb(255, 255, 255);" "border-radius:0px")); break; case 2: m_lineEidt[i]->setStyleSheet(QLatin1String( "border:1px solid #536874;\n" "border-left-color: rgb(255, 255, 255);\n" "border-top-color: rgb(0, 0, 0);\n" "border-bottom-color: rgb(0, 0, 0);\n" "border-right: 0px;\n" "border-left: 0px;\n" "border-right-color: rgb(255, 255, 255);" "border-radius:0px")); break; case 3: m_lineEidt[i]->setStyleSheet(QLatin1String( "border:1px solid #536874;\n" "border-left-color: rgb(255, 255, 255);\n" "border-top-color: rgb(0, 0, 0);\n" "border-bottom-color: rgb(0, 0, 0);\n" "border-left: 0px;\n" "border-right-color: rgb(0, 0, 0);" "border-radius:0px")); break; default: break; } pHBox->addWidget(m_lineEidt[i]); } this->setReadOnly(true); m_Color=Qt::white; connect(m_lineEidt[0],SIGNAL(textChanged(const QString &)),this,SLOT(OnLineEdit1TextChanged(const QString &))); connect(m_lineEidt[1],SIGNAL(textChanged(const QString &)),this,SLOT(OnLineEdit2TextChanged(const QString &))); connect(m_lineEidt[2],SIGNAL(textChanged(const QString &)),this,SLOT(OnLineEdit3TextChanged(const QString &))); connect(m_lineEidt[3],SIGNAL(textChanged(const QString &)),this,SLOT(OnLineEdit4TextChanged(const QString &))); } QIPLineEdit::~QIPLineEdit() { m_lineEidt[0]->deleteLater(); m_lineEidt[1]->deleteLater(); m_lineEidt[2]->deleteLater(); m_lineEidt[3]->deleteLater(); pHBox->deleteLater(); } void QIPLineEdit::MySetColor(QColor cr) { m_Color=cr; } void QIPLineEdit::OnLineEdit1TextChanged(const QString & strtemp) { if(strtemp.right(1)=="."||strtemp.right(1)=="。") { m_lineEidt[0]->setText(strtemp.left(strtemp.length()-1)); m_lineEidt[0 + 1]->setFocus(); m_lineEidt[0 + 1]->setCursorPosition(0); } } void QIPLineEdit::OnLineEdit2TextChanged(const QString & strtemp) { if(strtemp.right(1)=="."||strtemp.right(1)=="。") { m_lineEidt[1]->setText(strtemp.left(strtemp.length()-1)); m_lineEidt[1 + 1]->setFocus(); m_lineEidt[1 + 1]->setCursorPosition(0); } } void QIPLineEdit::OnLineEdit3TextChanged(const QString & strtemp) { if(strtemp.right(1)=="."||strtemp.right(1)=="。") { m_lineEidt[2]->setText(strtemp.left(strtemp.length()-1)); m_lineEidt[2 + 1]->setFocus(); m_lineEidt[2 + 1]->setCursorPosition(0); } } void QIPLineEdit::OnLineEdit4TextChanged(const QString & strtemp) { if(strtemp.right(1)=="."||strtemp.right(1)=="。") { m_lineEidt[3]->setText(strtemp.left(strtemp.length()-1)); } } void QIPLineEdit::paintEvent(QPaintEvent *event) { QWidget::paintEvent(event); QPainter painter(this); QBrush brush; int width = 0; for(int i = 0; i < 3; i++) { brush.setStyle(Qt::BrushStyle::SolidPattern); //将两个lineEdit之间的空隙绘制成白色 brush.setColor(m_Color); painter.setPen(m_Color); painter.setBrush(brush); painter.drawRect(m_lineEidt[i]->x() + m_lineEidt[i]->width(), m_lineEidt[i]->y(), SPACE, height()); //绘制空隙的边框 painter.setPen(Qt::black); painter.drawLine(0, 0, this->width(), 0); painter.drawLine(0, this->height() - 1, this->width(), this->height() - 1); //绘制小黑点 brush.setColor(Qt::black); painter.setPen(QPen()); painter.setBrush(brush); width += m_lineEidt[i]->width() + (i == 0 ? 2 : SPACE);//布局的间隔 painter.drawEllipse(width, height() / 2 + 4, 1, 1); } } 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(ev); QLineEdit *pEdit = qobject_cast(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() == 2 || (strText.length() < 2 && 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 QWidget::eventFilter(obj, ev); } break; case Qt::Key_Backspace: { 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 QWidget::eventFilter(obj, ev); } break; 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 QWidget::eventFilter(obj, ev); } break; 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 QWidget::eventFilter(obj, ev); } break; default: break; } } return false; } void QIPLineEdit::setText(const QString &strIP) { if (!isTextValid(strIP)) { QMessageBox::warning(this, "Attention", "Your IP Address is Invalid!["+strIP+"]", QMessageBox::StandardButton::Ok); return; } else { int i = 0; QStringList ipList = strIP.split("."); foreach (QString ip, 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"); return rx2.exactMatch(strIP); } QString QIPLineEdit::text() const { QString strIP; for (int i = 0; i < 4; i++) { strIP.append(m_lineEidt[i]->text()); if (i < 3) { strIP.append("."); } } return strIP; } void QIPLineEdit::MyClear() { m_lineEidt[0]->clear(); m_lineEidt[1]->clear(); m_lineEidt[2]->clear(); m_lineEidt[3]->clear(); }