Qt编写自定义控件:滑动验证控件

效果:

代码:

#ifndef DRAGSLIDERVERIFY_H
#define DRAGSLIDERVERIFY_H

#include <QWidget>

class DragSliderVerify : public QWidget
{
    Q_OBJECT

public:
    DragSliderVerify(QWidget *parent = nullptr);
    ~DragSliderVerify();

protected:
    void paintEvent(QPaintEvent *event)override;
    void mousePressEvent(QMouseEvent *event)override;
    void mouseReleaseEvent(QMouseEvent* event)override;
    void mouseMoveEvent(QMouseEvent *event)override;

private:
    enum class State
    {
        Unverified,
        Verifying,
        Verified
    };
    State verifyState{State::Unverified};
    int sliderX{0};//滑块左上角位置
    QRect sliderRect;
};
#endif // DRAGSLIDERVERIFY_H
#include "dragsliderverify.h"
#include <QPainter>
#include <QPaintEvent>
#include <QPainterPath>

DragSliderVerify::DragSliderVerify(QWidget *parent)
    : QWidget(parent)
{
    setFixedHeight(30);
    setMouseTracking(true);
}

DragSliderVerify::~DragSliderVerify()
{
}

void DragSliderVerify::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setPen(Qt::transparent);

    auto rect = event->rect();
    if(verifyState == State::Verified)
    {
        painter.fillRect(rect,QColor("#7AC23C"));
    }
    else
    {
        painter.fillRect(rect,QColor("#E8E8E8"));
    }

    auto font = painter.font();
    font.setPixelSize(16);
    painter.setFont(font);

    if(verifyState == State::Verified)
    {
        painter.setPen(Qt::white);
        painter.drawText(rect,Qt::AlignCenter,"验证通过");

        sliderRect = QRect(rect.width() - 35,0,35,30);
        painter.fillRect(sliderRect,Qt::white);
        QPainterPath path;
        path.addEllipse(sliderRect.center(),7,7);
        painter.fillPath(path,QColor("#7AC23C"));
        auto pathRect = path.boundingRect();
        painter.setPen(QPen(Qt::white,3,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin));
        painter.drawLine(QPoint(pathRect.x() + 4,14),QPoint(pathRect.x() + 6,17));
        painter.drawLine(QPoint(pathRect.x() + 6,17),QPoint(pathRect.x() + 10,11));
    }
    else
    {
        painter.setPen(QColor("#C0C0C0"));
        painter.fillRect(QRect(0,0,sliderX,30),QColor("#7AC23C"));
        painter.setBrush(Qt::white);

        painter.save();
        QPainterPath textRectPath;
        textRectPath.addRect(QRect(0,0,sliderX,30));
        painter.setClipPath(textRectPath);
        painter.setPen(Qt::white);
        painter.drawText(rect,Qt::AlignCenter,"拖动滑块验证");
        painter.restore();

        painter.save();
        textRectPath.clear();
        textRectPath.addRect(QRect(sliderX + 30,0,rect.width() - sliderX - 30,30));
        painter.setClipPath(textRectPath);
        painter.setPen(Qt::black);
        painter.drawText(rect,Qt::AlignCenter,"拖动滑块验证");
        painter.restore();

        sliderRect = QRect(sliderX,0,35,30);
        painter.drawRect(sliderRect);

        painter.setPen(QPen(QColor("#C0C0C0"),2,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin));

        painter.drawLine(QPoint(sliderX + 10,10),QPoint(sliderX + 15,15));
        painter.drawLine(QPoint(sliderX + 15,15),QPoint(sliderX + 10,20));

        painter.drawLine(QPoint(sliderX + 20,10),QPoint(sliderX + 25,15));
        painter.drawLine(QPoint(sliderX + 25,15),QPoint(sliderX + 20,20));
    }
}

void DragSliderVerify::mousePressEvent(QMouseEvent *event)
{
    if(verifyState == State::Unverified)
    {
        if(sliderRect.contains(event->pos()))
        {
            verifyState = State::Verifying;
        }
    }
    QWidget::mousePressEvent(event);
}

void DragSliderVerify::mouseReleaseEvent(QMouseEvent* event)
{
    if(verifyState == State::Verifying)
    {
        verifyState = State::Unverified;
        setCursor(Qt::ArrowCursor);
        sliderX = 0;
        update();
    }
    QWidget::mouseReleaseEvent(event);
}

void DragSliderVerify::mouseMoveEvent(QMouseEvent *event)
{
    if(sliderRect.contains(event->pos()))
    {
        if(verifyState != State::Verified)
        {
            setCursor(Qt::SizeAllCursor);
        }
        else
        {
            setCursor(Qt::ArrowCursor);
        }
    }
    else
    {
        setCursor(Qt::ArrowCursor);
    }

    if(verifyState == State::Verifying)
    {
        auto posX = event->pos().x();
        sliderX = std::max(posX - sliderRect.width()/2,0);
        if(sliderX >= (rect().width() - sliderRect.width()))
        {
            setCursor(Qt::SizeAllCursor);
            verifyState = State::Verified;
        }
        update();
    }
    QWidget::mouseMoveEvent(event);
}

这个控件别的没啥,唯一要注意的点在于滑块两边的文字颜色不同,原理是确定两个绘制区域、设置两次裁剪路径并用不同颜色绘制两次文字。

实践出真知。

Guess you like

Origin blog.csdn.net/kenfan1647/article/details/121310717