手势密码

Qt模仿安卓手势登陆密码
在这里插入图片描述
头文件

#ifndef QWHGESTURELOGIN_H
#define QWHGESTURELOGIN_H

#include <QWidget>
#include <QPaintEvent>
#include <QPainter>
#include <QMouseEvent>

class QWHGestureLogin : public QWidget
{
    Q_OBJECT
public:
    struct PosInCircle
    {
        int i;      //行
        int j;      //列
        bool isIn;  //是否在范围内
    };
    explicit QWHGestureLogin(QWidget *parent = nullptr);
    ~QWHGestureLogin();

    void setPassword(const QString password);
    QString getPassword();
    bool checkPassword();
protected:
    void paintEvent(QPaintEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mousePressEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    void drawBg(QPainter *painter);
    void drawOutCircle(QPainter *painter);
    void drawTipLine(QPainter *painter);
    void drawInCircle(QPainter *painter);
    void drawJoinLine(QPainter *painter);
private:
    double distance(int x1, int y1, int x2, int y2);
    int posToNumber(int i, int j);
signals:
    void correctPassword(bool isCorrect, QString password);
public slots:
private:
    QColor m_bgColor;                   //背景色
    QColor m_outCircleColor;            //外圆颜色
    QColor m_tipLineColor;              //提示线颜色
    QColor m_circleRingColor;           //圆环颜色
    int m_margin;                       //外边距
    int m_radius;                       //圆相对半径
    PosInCircle m_posInCircle;          //判断点是否在圆内
    bool m_pressed;                     //鼠标按下
    bool m_showText;                    //是否显示文字

    QVector<QPoint> m_vecInputPoints;   //鼠标移动选点
    QPoint m_followPoint;               //鼠标跟随点
    QString m_password;                 //原密码
    QString m_inputPassword;            //鼠标移动选点转换为密码
};

#endif // QWHGESTURELOGIN_H

核心代码

void QWHGestureLogin::paintEvent(QPaintEvent *event)
{
    int width = this->width();
    int height = this->height();
    int side = qMin(width, height);

    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.translate(width / 2, height / 2);
    painter.scale(side / 200, side / 200);

    drawBg(&painter);
    drawOutCircle(&painter);
    drawTipLine(&painter);
    drawInCircle(&painter);
    drawJoinLine(&painter);
}
void QWHGestureLogin::drawBg(QPainter *painter)
{
    painter->save();

    int width = this->width();
    int height = this->height();

    painter->setPen(Qt::NoPen);
    painter->setBrush(m_bgColor);
    painter->drawRect(-width / 2, -height / 2, width, height);

    painter->restore();
}

void QWHGestureLogin::drawOutCircle(QPainter *painter)
{
    painter->save();
    QPen pen(m_outCircleColor, 2);
    painter->setPen(pen);
    painter->setBrush(Qt::NoBrush);

    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            int x = -5 * m_radius + j * 4 * m_radius;
            int y = -5 * m_radius + i * 4 * m_radius;
            painter->drawEllipse(x, y, m_radius * 2, m_radius * 2);

            if (m_showText)
            {
                int number = posToNumber(i, j);
                QString text = QString::number(number);
                x = -4 * m_radius + j * 4 * m_radius;
                y = -4 * m_radius + i * 4 * m_radius;
                int textWidth = fontMetrics().width(text);
                int textHeight = fontMetrics().height();
                painter->drawText(x - textWidth / 2, y + textWidth / 2, text);
            }
        }
    }

    painter->restore();
}

void QWHGestureLogin::drawTipLine(QPainter *painter)
{
    painter->save();

    int offset = 3;
    
    if (m_posInCircle.isIn)
    {
        if (!m_pressed)
        {
            painter->setPen(m_tipLineColor);
            painter->setBrush(Qt::NoBrush);

            int x = -m_radius * 5 + m_posInCircle.j * 4 * m_radius - offset;
            int y = -m_radius * 5 + m_posInCircle.i * 4 * m_radius - offset;
            int w = (m_radius + offset) * 2;
            int h = (m_radius + offset) * 2;
            QRect rect(x, y, w, h);
            painter->drawEllipse(rect);
        }
    }

    painter->restore();
}

void QWHGestureLogin::drawInCircle(QPainter *painter)
{
    painter->save();

    if (m_pressed)
    {
        int offset1 = 1;//圆环偏移量
        int offset2 = 3;//内圆偏移量

        if (m_posInCircle.isIn)
        {
            //绘制圆环
            painter->setPen(m_circleRingColor);
            painter->setBrush(m_circleRingColor);
            int x = -m_radius * 5 + m_posInCircle.j * 4 * m_radius + offset1;
            int y = -m_radius * 5 + m_posInCircle.i * 4 * m_radius + offset1;
            int w = (m_radius - offset1) * 2;
            int h = (m_radius - offset1) * 2;
            QRect rect(x, y, w, h);
            painter->drawEllipse(rect);

            painter->setPen(m_outCircleColor);
            painter->setBrush(m_outCircleColor);
            x = -m_radius * 5 + m_posInCircle.j * 4 * m_radius + offset2;
            y = -m_radius * 5 + m_posInCircle.i * 4 * m_radius + offset2;
            w = (m_radius - offset2) * 2;
            h = (m_radius - offset2) * 2;
            rect = QRect(x, y, w, h);
            painter->drawEllipse(rect);

            x = -m_radius * 4 + m_posInCircle.j * 4 * m_radius;
            y = -m_radius * 4 + m_posInCircle.i * 4 * m_radius;

            if (!m_vecInputPoints.contains(QPoint(x, y)))
            {
                m_vecInputPoints.push_back(QPoint(x, y));
                int number = posToNumber(m_posInCircle.i, m_posInCircle.j);
                m_inputPassword += QString::number(number);
            }
        }
    }

    painter->restore();
}

void QWHGestureLogin::drawJoinLine(QPainter *painter)
{
    painter->save();

    QPen pen(m_outCircleColor, 3);
    painter->setPen(pen);
	//绘制连接线段
    for (int i = 0; i < m_vecInputPoints.count() - 1; i++)
    {
        painter->drawLine(m_vecInputPoints[i], m_vecInputPoints[i + 1]);
    }

    int offset1 = 1;//圆环偏移量
    int offset2 = 3;//内圆偏移量
    //绘制连接圆
    for (int i = 0; i < m_vecInputPoints.count(); i++)
    {
        int x = m_vecInputPoints[i].x() - m_radius + offset1;
        int y = m_vecInputPoints[i].y() - m_radius + offset1;
        int w = 2 * (m_radius - offset1);
        int h = 2 * (m_radius - offset1);
        painter->setPen(m_circleRingColor);
        painter->setBrush(m_circleRingColor);
        painter->drawEllipse(x, y, w, h);

        x = m_vecInputPoints[i].x() - m_radius + offset2;
        y = m_vecInputPoints[i].y() - m_radius + offset2;
        w = 2 * (m_radius - offset2);
        h = 2 * (m_radius - offset2);
        painter->setPen(m_outCircleColor);
        painter->setBrush(m_outCircleColor);
        painter->drawEllipse(x, y, w, h);
    }
    //绘制跟随线
    if (m_pressed && m_vecInputPoints.count() < 9)
	{
    	int width = this->width();
    	int height = this->height();
   	 	int side = qMin(width, height);
    	int scale = side / 200;
    	int x = (m_followPoint.x() - width / 2) / scale;
   		int y = (m_followPoint.y() - height / 2) / scale;
    	if (m_vecInputPoints.count() > 0)
    	{
        	painter->setPen(pen);
        	painter->drawLine(m_vecInputPoints.last(), QPoint(x, y));
    	}
}

    painter->restore();
}
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浮生卍流年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值