• 5517阅读
  • 8回复

IP地址·输入控件 [复制链接]

上一主题 下一主题
离线xiaoke123
 

只看楼主 正序阅读 楼主  发表于: 2020-07-01
— 本帖被 20091001753 从 Qt 作品展 移动到本区(2020-07-02) —
由于用刘总的IP设置背景和边框圆角不生效,又想区别当前焦点状态,故改了一个
IP控件QIPLineEdit部分功能参考刘总和网上一些代码,实现还是有区别,具体功能如下:
IP地址输入框控件
1:可设置IP地址,自动填入框
2:可清空IP地址
3:支持按下小圆点自动切换
4:支持退格键自动切换
5:支持IP地址过滤
6:可设置/边框颜色/边框圆角角度
7.支持焦点切换高亮不同边框颜色
效果可看如下动态图

真实应用效果,遥控器切焦点


关键代码在:paintEvent 和 eventFilter
h头文件
  1. /************************************************************************/
  2. /* Modified by:xiaoke
  3.    QQ:1035144170
  4. */
  5. /************************************************************************/
  6. #ifndef QIPLINEEDIT_H
  7. #define QIPLINEEDIT_H
  8. #include <QLineEdit>
  9. #include <QEvent>
  10. class QIPLineEdit : public QLineEdit
  11. {
  12.     Q_OBJECT
  13. public:
  14.     QIPLineEdit(QWidget *parent = 0);
  15.     ~QIPLineEdit();
  16.     //设置IP字符
  17.     void setText(const QString &strIP);
  18.     //当前IP字符
  19.     QString text() const;
  20.     //设置焦点边框颜色
  21.     void setFocusBorderColor(const QString &focusColor);
  22.     //设置边框颜色
  23.     void setBorderColor(const QString &borderColor);
  24.     //设置边框圆角角度
  25.     void setBorderRadius(int borderRadius);
  26.     //清空ip字符
  27.     void clear();
  28.     //设置当前焦点
  29.     void setFocus();
  30. protected:
  31.     void paintEvent(QPaintEvent *event);
  32.     bool eventFilter(QObject *obj, QEvent *ev);
  33.     int getIndex(QLineEdit *pEdit);
  34.     bool isTextValid(const QString &strIP);
  35. private:
  36.     QLineEdit *m_lineEidt[4];
  37.     QString focusColor; //焦点边框颜色
  38.     QString borderColor;//边框颜色
  39.     int borderRadius;   //边框圆角角度
  40. };
  41. #endif // QIPLINEEDIT_H
CPP实现
  1. /************************************************************************/
  2. /* Modified by:xiaoke
  3.    QQ:1035144170
  4. */
  5. /************************************************************************/
  6. #include "qiplineedit.h"
  7. #include <QRegExpValidator>
  8. #include <QPainter>
  9. #include <QHBoxLayout>
  10. #include <QKeyEvent>
  11. #include <QMessageBox>
  12. #include <QDebug>
  13. #pragma execution_character_set("utf-8")
  14. QIPLineEdit::QIPLineEdit(QWidget *parent)
  15.     : QLineEdit(parent)
  16. {
  17.     focusColor  = "#26282C";
  18.     borderColor = "#26282C";
  19.     borderRadius = 3;
  20.     this->setStyleSheet(QString("QIPLineEdit{border:1px solid %1;border-radius:%2px;}").arg(borderColor).arg(borderRadius));
  21.     QRegExp rx("(2[0-5]{2}|2[0-4][0-9]|1?[0-9]{1,2})");
  22.     QHBoxLayout *pHBox = new QHBoxLayout(this);
  23.     pHBox->setSpacing(10);
  24.     pHBox->setContentsMargins(5, 5, 5, 5);
  25.     for (int i = 0; i < 4; i++)
  26.     {
  27.         m_lineEidt[i] = new QLineEdit(this);
  28.         m_lineEidt[i]->setFrame(false);
  29.         m_lineEidt[i]->setMaxLength(3);
  30.         m_lineEidt[i]->setAlignment(Qt::AlignCenter);
  31.         m_lineEidt[i]->installEventFilter(this);
  32.         m_lineEidt[i]->setValidator(new QRegExpValidator(rx, this));
  33.         m_lineEidt[i]->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
  34.         pHBox->addWidget(m_lineEidt[i]);
  35.     }
  36.     this->setReadOnly(true);
  37. }
  38. QIPLineEdit::~QIPLineEdit()
  39. {
  40. }
  41. void QIPLineEdit::paintEvent(QPaintEvent *event)
  42. {
  43.     __super::paintEvent(event);
  44.     QPainter painter(this);
  45.     QBrush brush;
  46.     brush.setStyle(Qt::BrushStyle::SolidPattern);
  47.     brush.setColor(Qt::black);
  48.     painter.setBrush(brush);
  49.     //qDebug()  << "xiaoke painter";
  50.     int width = 0;
  51.     for (int i = 0; i < 3; i++)
  52.     {
  53.         width += m_lineEidt[i]->width() + (i == 0 ? 7 : 10);//布局的间隔
  54.         painter.drawEllipse(width, height() / 2 - 2, 4, 4);
  55.     }
  56. }
  57. int QIPLineEdit::getIndex(QLineEdit *pEdit)
  58. {
  59.     int index = -1;
  60.     for (int i = 0; i < 4; i++)
  61.     {
  62.         if (pEdit == m_lineEidt[i])
  63.             index = i;
  64.     }
  65.     return index;
  66. }
  67. bool QIPLineEdit::eventFilter(QObject *obj, QEvent *ev)
  68. {
  69.     if (children().contains(obj) && QEvent::KeyPress == ev->type())
  70.     {
  71.         QKeyEvent *keyEvent = dynamic_cast<QKeyEvent *>(ev);
  72.         QLineEdit *pEdit = qobject_cast<QLineEdit *>(obj);
  73.         switch (keyEvent->key())
  74.         {
  75.         case Qt::Key_0:
  76.         case Qt::Key_1:
  77.         case Qt::Key_2:
  78.         case Qt::Key_3:
  79.         case Qt::Key_4:
  80.         case Qt::Key_5:
  81.         case Qt::Key_6:
  82.         case Qt::Key_7:
  83.         case Qt::Key_8:
  84.         case Qt::Key_9:
  85.         {
  86.             QString strText = pEdit->text();
  87.             if (pEdit->selectedText().length())
  88.             {
  89.                 pEdit->text().replace(pEdit->selectedText(), QChar(keyEvent->key()));
  90.             }
  91.             else if (strText.length() == 3 || strText.length() < 3 && strText.toInt() * 10 > 255)
  92.             {
  93.                 int index = getIndex(pEdit);
  94.                 if (index != -1 && index != 3)
  95.                 {
  96.                     m_lineEidt[index + 1]->setFocus();
  97.                     m_lineEidt[index + 1]->selectAll();
  98.                 }
  99.             }
  100.             else if (strText.length() == 2 && strText.toInt() * 10 < 255)
  101.             {
  102.                 if (Qt::Key_0 == keyEvent->key() && strText.toInt())
  103.                 {
  104.                     pEdit->setText(strText.insert(pEdit->cursorPosition(), QChar(Qt::Key_0)));
  105.                 }
  106.             }
  107.             return __super::eventFilter(obj, ev);
  108.         }
  109.         break;
  110.         case Qt::Key_Period:
  111.         {
  112.             this->focusNextChild();
  113.         }
  114.         break;
  115.         case Qt::Key_Backspace:
  116.         {
  117.             if (pEdit->text().length() <= 1)
  118.                 this->focusNextPrevChild(false);
  119.             QString strText = pEdit->text();
  120.             if (!strText.length() || strText.length() && !pEdit->cursorPosition())
  121.             {
  122.                 int index = getIndex(pEdit);
  123.                 if (index != -1 && index != 0)
  124.                 {
  125.                     m_lineEidt[index - 1]->setFocus();
  126.                     int length = m_lineEidt[index - 1]->text().length();
  127.                     m_lineEidt[index - 1]->setCursorPosition(length ? length : 0);
  128.                 }
  129.             }
  130.             return __super::eventFilter(obj, ev);
  131.         }
  132.         case Qt::Key_Left:
  133.         {
  134.             if (!pEdit->cursorPosition())
  135.             {
  136.                 int index = getIndex(pEdit);
  137.                 if (index != -1 && index != 0)
  138.                 {
  139.                     m_lineEidt[index - 1]->setFocus();
  140.                     int length = m_lineEidt[index - 1]->text().length();
  141.                     m_lineEidt[index - 1]->setCursorPosition(length ? length : 0);
  142.                 }
  143.             }
  144.             return __super::eventFilter(obj, ev);
  145.         }
  146.         case Qt::Key_Right:
  147.         {
  148.             if (pEdit->cursorPosition() == pEdit->text().length())
  149.             {
  150.                 int index = getIndex(pEdit);
  151.                 if (index != -1 && index != 3)
  152.                 {
  153.                     m_lineEidt[index + 1]->setFocus();
  154.                     m_lineEidt[index + 1]->setCursorPosition(0);
  155.                 }
  156.             }
  157.             return __super::eventFilter(obj, ev);
  158.         }
  159.         default:
  160.             break;
  161.         }
  162.     }
  163.     return false;
  164. }
  165. void QIPLineEdit::setText(const QString &strIP)
  166. {
  167.     if (!isTextValid(strIP))
  168.     {
  169.         QMessageBox::warning(this, "Attention", "Your IP Address is Invalid!", QMessageBox::StandardButton::Ok);
  170.         return;
  171.     }
  172.     else
  173.     {
  174.         int i = 0;
  175.         QStringList ipList = strIP.split(".");
  176.         for each (QString ip in ipList)
  177.         {
  178.             m_lineEidt[i]->setText(ip);
  179.             i++;
  180.         }
  181.     }
  182. }
  183. bool QIPLineEdit::isTextValid(const QString &strIP)
  184. {
  185.     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");
  186.     if (!rx2.exactMatch(strIP))
  187.         return false;
  188.     return true;
  189. }
  190. QString QIPLineEdit::text() const
  191. {
  192.     QString strIP;
  193.     for (int i = 0; i < 4; i++)
  194.     {
  195.         strIP.append(m_lineEidt[i]->text());
  196.         if(i == 3)
  197.             continue;
  198.         strIP.append(".");
  199.     }
  200.     //qDebug()  << strIP;
  201.     return strIP;
  202. }
  203. void QIPLineEdit::clear()
  204. {
  205.     for (int i = 0; i < 4; i++)
  206.         m_lineEidt[i]->clear();
  207. }
  208. void QIPLineEdit::setFocus()
  209. {
  210.     m_lineEidt[0]->setFocus();
  211.     /*for (int i = 0; i < 4; i++)
  212.     {
  213.         if(m_lineEidt[i]->text().isNull())
  214.             m_lineEidt[i]->setFocus();
  215.         else
  216.         {
  217.             m_lineEidt[i]->setFocus();
  218.         }
  219.     }*/
  220.     if (m_lineEidt[0]->hasFocus() || m_lineEidt[1]->hasFocus() || m_lineEidt[2]->hasFocus() || m_lineEidt[3]->hasFocus())
  221.     {
  222.         this->setStyleSheet(QString("QIPLineEdit{border:2px solid %1;border-radius:%2px;}").arg(focusColor).arg(borderRadius));
  223.     }else
  224.     {
  225.         this->setStyleSheet(QString("QIPLineEdit{border:1px solid %1;border-radius:%2px;}").arg(borderColor).arg(borderRadius));
  226.     }
  227. }
  228. void QIPLineEdit::setFocusBorderColor(const QString &focusColor)
  229. {
  230.     if (this->focusColor != focusColor) {
  231.         this->focusColor = focusColor;
  232.     }
  233. }
  234. void QIPLineEdit::setBorderColor(const QString &borderColor)
  235. {
  236.     if (this->borderColor != borderColor) {
  237.         this->borderColor = borderColor;
  238.     }
  239. }
  240. void QIPLineEdit::setBorderRadius(int borderRadius)
  241. {
  242.     if (this->borderRadius != borderRadius) {
  243.         this->borderRadius = borderRadius;
  244.     }
  245. }

相关使用方法:

代码后面就不一一列,想看区别之处可下附件看源码吧!如有什么更好的建议和方法,多多交流 ipaddress.zip (9 K) 下载次数:76
ipaddress0724.zip (9 K) 下载次数:153






4条评分好评度+1贡献值+1金钱+10威望+1
20091001753 好评度 +1 - 2020-07-02
20091001753 贡献值 +1 - 2020-07-02
20091001753 威望 +1 - 2020-07-02
20091001753 金钱 +10 - 2020-07-02
离线梦幻风

只看该作者 8楼 发表于: 2023-06-17
谢谢!大佬,学习了
离线白马

只看该作者 7楼 发表于: 2022-09-20
回 cllssg 的帖子
cllssg:__super::paintEvent(event);编译不过去,是怎么回事?提示__super没有定义。 (2021-05-13 17:54) 

如果用mingW的编译器 将//    __super::paintEvent(event);替换成 QLineEdit::paintEvent(event);
相应的//            return __super::eventFilter(obj, ev);替换为 return QLineEdit::eventFilter(obj,ev);

和 //        for each (QString ip in ipList)
//        {
//            m_lineEidt->setText(ip);
//            i++;
//        }
        foreach (QString ip , ipList)
        {
            m_lineEidt->setText(ip);
            i++;
        }
离线zipl1985

只看该作者 6楼 发表于: 2022-07-23
学习了,
离线清风煮酒

只看该作者 5楼 发表于: 2021-11-29
多谢大佬,小弟学习学习。
路漫漫,其修远兮,吾将上下而求索。
离线cllssg

只看该作者 4楼 发表于: 2021-05-13
__super::paintEvent(event);编译不过去,是怎么回事?提示__super没有定义。
离线dxa572862121

只看该作者 3楼 发表于: 2020-07-08
     伸手党到此一游
离线xiaoke123

只看该作者 2楼 发表于: 2020-07-01
回 liudianwu 的帖子
liudianwu:牛逼,原来是小可大佬, [表情]  [表情]  (2020-07-01 12:59) 

别啊 我算不上 刘大才是啊 那么谦虚干嘛
离线liudianwu

只看该作者 1楼 发表于: 2020-07-01
牛逼,原来是小可大佬,   
欢迎关注微信公众号:Qt实战 (各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发)QQ:517216493  WX:feiyangqingyun  QQ群:751439350
快速回复
限100 字节
 
上一个 下一个