首页 > 其他分享 >自定义的Qt IP地址编辑控件

自定义的Qt IP地址编辑控件

时间:2022-11-17 20:27:45浏览次数:49  
标签:控件 Qt 自定义 MIpAddressEditor QLineEdit leIp4 leIp3 leIp2

模仿WIndows系统的IP地址编辑框创建的控件。在VS2015和Qt5.9上测试通过。效果图如下:

上代码,头文件:

class QLineEdit;

class MIpAddressEditor : public QWidget
{
    Q_OBJECT

public:
    MIpAddressEditor(QWidget* parent = 0);
    void setIp(const QString& ip);
    QString ip() const;

private:
    bool eventFilter(QObject *watched, QEvent *event) override;
    void paintEvent(QPaintEvent*) override;
    QSize sizeHint() const override;

private slots:
    void leIpTextChanged(const QString& text);

private:
    bool focused;
    QLineEdit *leIp1;
    QLineEdit *leIp2;
    QLineEdit *leIp3;
    QLineEdit *leIp4;
};

CPP文件:

MIpAddressEditor::MIpAddressEditor(QWidget* parent) :
    QWidget(parent), focused(false)
{
    setStyleSheet(u8"* { background-color:white; }");
    QHBoxLayout* lay = new QHBoxLayout();
    lay->setContentsMargins(1, 1, 1, 1);
    lay->setSpacing(0);
    QLabel* label1 = new QLabel(u8".", this);
    QLabel* label2 = new QLabel(u8".", this);
    QLabel* label3 = new QLabel(u8".", this);
    leIp1 = new QLineEdit(this);
    leIp1->setStyleSheet(u8"QLineEdit { border:none; }");
    leIp1->setAlignment(Qt::AlignCenter);
    leIp2 = new QLineEdit(this);
    leIp2->setStyleSheet(u8"QLineEdit { border:none; }");
    leIp2->setAlignment(Qt::AlignCenter);
    leIp3 = new QLineEdit(this);
    leIp3->setStyleSheet(u8"QLineEdit { border:none; }");
    leIp3->setAlignment(Qt::AlignCenter);
    leIp4 = new QLineEdit(this);
    leIp4->setStyleSheet(u8"QLineEdit { border:none; }");
    leIp4->setAlignment(Qt::AlignCenter);
    lay->addWidget(leIp1);
    lay->addWidget(label1);
    lay->addWidget(leIp2);
    lay->addWidget(label2);
    lay->addWidget(leIp3);
    lay->addWidget(label3);
    lay->addWidget(leIp4);
    setLayout(lay);

    QIntValidator* validator = new QIntValidator(this);
    validator->setRange(0, 255);
    leIp1->setValidator(validator);
    leIp2->setValidator(validator);
    leIp3->setValidator(validator);
    leIp4->setValidator(validator);
    leIp1->installEventFilter(this);
    leIp2->installEventFilter(this);
    leIp3->installEventFilter(this);
    leIp4->installEventFilter(this);
    connect(leIp1, &QLineEdit::textChanged, this, &MIpAddressEditor::leIpTextChanged);
    connect(leIp2, &QLineEdit::textChanged, this, &MIpAddressEditor::leIpTextChanged);
    connect(leIp3, &QLineEdit::textChanged, this, &MIpAddressEditor::leIpTextChanged);
    connect(leIp4, &QLineEdit::textChanged, this, &MIpAddressEditor::leIpTextChanged);
}

void MIpAddressEditor::setIp(const QString& ip)
{
    QStringList nums = ip.split('.');
    if (nums.size() == 4)
    {
        leIp1->setText(nums[0]);
        leIp2->setText(nums[1]);
        leIp3->setText(nums[2]);
        leIp4->setText(nums[3]);
    }
}

QString MIpAddressEditor::ip() const
{
    QString ipAddr = QString(u8"%1.%2.%3.%4")
        .arg(leIp1->text(), leIp2->text(), leIp3->text(), leIp4->text());
    return ipAddr;
}

bool MIpAddressEditor::eventFilter(QObject *watched, QEvent *event)
{
    if (event->type() == QEvent::KeyPress)
    {
        const QVarLengthArray<QWidget*, 4> editors = { leIp1, leIp2, leIp3, leIp4 };
        QKeyEvent* keyEvent = dynamic_cast<QKeyEvent*>(event);
        QWidget* target = dynamic_cast<QWidget*>(watched);
        if (keyEvent->key() == Qt::Key_Space)
        {
            if (target != editors.back())
            {
                editors[editors.indexOf(target) + 1]->setFocus();
            }
            return true;
        }
    }
    else if (event->type() == QEvent::FocusIn)
    {
        focused = true;
        update();
    }
    else if (event->type() == QEvent::FocusOut)
    {
        if (!leIp1->hasFocus() && !leIp2->hasFocus() &&
            !leIp3->hasFocus() && !leIp4->hasFocus())
        {
            focused = false;
            update();
        }
    }
    return false;
}

void MIpAddressEditor::leIpTextChanged(const QString& text)
{
    if (text.size() >= 3)
    {
        const QVarLengthArray<QWidget*, 4> editors = { leIp1, leIp2, leIp3, leIp4 };
        QWidget* src = dynamic_cast<QWidget*>(sender());
        if (src != editors.back())
        {
            editors[editors.indexOf(src) + 1]->setFocus();
        }
    }
}

void MIpAddressEditor::paintEvent(QPaintEvent*)
{
    QStyleOption opt;
    opt.init(this);
    QPainter painter(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
    QPalette pale = palette();
    painter.setBrush(Qt::NoBrush);
    if (focused)
    {
        painter.setPen(QPen(pale.highlight(), 1));
        painter.drawRect(0, 0, width() - 1, height() - 1);
    }
    else
    {
        painter.setPen(QPen(pale.mid(), 1));
        painter.drawRect(0, 0, width() - 1, height() - 1);
    }
}

QSize MIpAddressEditor::sizeHint() const
{
    return QSize(160, 24);
}

上述代码中重写sizeHint函数是为了给控件一个默认大小。附Qt控件的sizePolicy枚举项说明:

控件的sizePolicy说明控件在布局管理中的缩放方式。Qt提供的控件都有一个合理的缺省sizePolicy,但是这个缺省值有时不能适合所有的布局,开发人员经常需要改变窗体上的某些控件的sizePolicy。下面列举了一些最常用的值(©著作权归作者所有:来自51CTO博客作者mb62b19580f1ddc的原创作品,https://blog.51cto.com/u_15692960/5405785)

  1. Fixed:控件不能放大或者缩小,控件的大小就是它的sizeHint。
  2. Minimum:控件的sizeHint为控件的最小尺寸。控件不能小于这个sizeHint,但是可以放大。
  3. Maximum:控件的sizeHint为控件的最大尺寸,控件不能放大,但是可以缩小到它的最小的允许尺寸。
  4. Preferred:控件的sizeHint是它的sizeHint,但是可以放大或者缩小
  5. Expanding:控件可以自行增大或者缩小

标签:控件,Qt,自定义,MIpAddressEditor,QLineEdit,leIp4,leIp3,leIp2
From: https://www.cnblogs.com/mengxiangdu/p/16900649.html

相关文章