qt/LedOK/base/qiplineedit.cpp
2023-04-18 14:14:46 +08:00

286 lines
10 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* 此类的封装参考了博客网址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 <QRegExpValidator>
#include <QPainter>
#include <QKeyEvent>
#include <QMessageBox>
#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<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() == 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();
}