基于Qt实现Android的图案密码效果
作者:小灰灰搞电子
这篇文章主要为大家详细介绍了如何基于Qt实现Android的图案密码效果,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起了解一下
一、效果展示
二、源码分享
PatternPasswordWidget .hpp
#ifndef PATTERNCODELOCKWIDGET_H #define PATTERNCODELOCKWIDGET_H #include <QWidget> #include <QWidget> #include <QTimer> class PatternPasswordWidget : public QWidget { Q_OBJECT public: PatternPasswordWidget(QWidget *parent = nullptr); ~PatternPasswordWidget()override; void reset(); int getNumberOfEachRowAndCol() const; void setNumberOfEachRowAndCol(int newNumberOfEachRowAndCol); signals: void inputPasswordOverSignal(QString); protected: void paintEvent(QPaintEvent *event)override; void resizeEvent(QResizeEvent *event) override; void mouseMoveEvent(QMouseEvent *event)override; void mousePressEvent(QMouseEvent *event)override; void mouseReleaseEvent(QMouseEvent *event)override; void mouseDoubleClickEvent(QMouseEvent *event)override; private: void onHoverTimer(); QString getPassWord(); enum class CircularState { normal,//正常 hoverOnInnerSamrtCircular//鼠标悬浮在中间的小圆上面 }; enum class PatternCodeLockState { notSet, setting, setted_valid,//有效 setted_invalid//无效 }; int numberOfEachRowAndCol; PatternCodeLockState patternCodeLockSetUpState{PatternCodeLockState::notSet}; QList<CircularState> circularStateList; QList<QRect> smartCircularRectList; bool isUpdateSmartCircularRect{true}; QTimer hoverTimer; int radiu; int lastHoverIndex{-1}; int currentchangeLength; bool mouseInSomeSmartCircular{false}; QList<int> setList; QPoint settingMousPos; }; #endif // PATTERNCODELOCKWIDGET_H
PatternPasswordWidget .cpp
#include "patternPasswordWidget.h" #include <QPainter> #include <QPainterPath> #include <QPaintEvent> PatternPasswordWidget::PatternPasswordWidget(QWidget *parent) : QWidget(parent) { setMouseTracking(true); setMinimumSize(400,400); numberOfEachRowAndCol = 3; for (int i = 0;i < numberOfEachRowAndCol;++i) { for (int j = 0;j < numberOfEachRowAndCol;++j) { circularStateList << CircularState::normal; smartCircularRectList << QRect(); } } connect(&hoverTimer,&QTimer::timeout,this,&PatternPasswordWidget::onHoverTimer); hoverTimer.setInterval(40); } PatternPasswordWidget::~PatternPasswordWidget() { } void PatternPasswordWidget::paintEvent(QPaintEvent *event) { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing,true); const auto rect = event->rect(); painter.fillRect(rect,QColor("#1D1D1D")); auto width = rect.width(); auto height = rect.height(); auto sideLength = std::min(width,height) - 20; auto halfSideLength = sideLength/2; QRect drawZoneRect = QRect(-halfSideLength,-halfSideLength,sideLength,sideLength); drawZoneRect.translate(rect.center()); painter.save(); painter.setPen(QPen(QBrush("#141414"),5)); painter.drawRoundedRect(drawZoneRect,12,12); painter.restore(); radiu = sideLength / (1 + 1 + numberOfEachRowAndCol * 2 + (numberOfEachRowAndCol - 1) * 3); bool mustUpdateCircularRect = isUpdateSmartCircularRect; for (int i = 0,listIndex = 0;i < numberOfEachRowAndCol;++i) { for (int j = 0;j < numberOfEachRowAndCol;++j,++listIndex) { QPoint circularCenter = drawZoneRect.topLeft() + QPoint(2*radiu + i*5*radiu,2*radiu + j*5*radiu); if(setList.contains(listIndex)) { if(patternCodeLockSetUpState == PatternCodeLockState::setting || patternCodeLockSetUpState == PatternCodeLockState::setted_valid) { painter.setPen(QPen(QBrush(QColor("#00FF80")),3)); } else { painter.setPen(QPen(QBrush(QColor("#FE4C40")),3)); } } else { painter.setPen(QPen(QBrush(Qt::white),3)); } if(listIndex == lastHoverIndex && hoverTimer.isActive() && patternCodeLockSetUpState == PatternCodeLockState::setting) { painter.drawEllipse(circularCenter,radiu + currentchangeLength,radiu + currentchangeLength); } else { painter.drawEllipse(circularCenter,radiu,radiu); } if(mustUpdateCircularRect) { QRect newCircularRect = QRect(-radiu/2,-radiu/2,radiu,radiu); newCircularRect.translate(circularCenter); smartCircularRectList[listIndex] = newCircularRect; } painter.save(); switch (circularStateList.at(listIndex)) { case CircularState::normal: { if(listIndex == lastHoverIndex && hoverTimer.isActive() && patternCodeLockSetUpState == PatternCodeLockState::notSet) { painter.setBrush(Qt::white); painter.setPen(Qt::transparent); painter.drawEllipse(circularCenter, static_cast<int>(radiu * 0.5 + currentchangeLength), static_cast<int>(radiu * 0.5 + currentchangeLength)); } else { painter.setBrush(QColor("#888888")); painter.setPen(Qt::transparent); painter.drawEllipse(circularCenter,radiu/2,radiu/2); } }break; case CircularState::hoverOnInnerSamrtCircular: { painter.setPen(Qt::transparent); if(patternCodeLockSetUpState == PatternCodeLockState::notSet) { painter.setBrush(Qt::white); if(hoverTimer.isActive()) { painter.drawEllipse(circularCenter, static_cast<int>(radiu * 0.5 + currentchangeLength), static_cast<int>(radiu * 0.5 + currentchangeLength)); } else { painter.drawEllipse(circularCenter, static_cast<int>(radiu * 0.7), static_cast<int>(radiu * 0.7)); } } else { if(patternCodeLockSetUpState == PatternCodeLockState::setting || patternCodeLockSetUpState == PatternCodeLockState::setted_valid) { painter.setBrush(QColor("#00FF80")); } else { painter.setBrush(QColor("#FE4C40")); } painter.drawEllipse(circularCenter, static_cast<int>(radiu * 0.7), static_cast<int>(radiu * 0.7)); } }break; } painter.restore(); } } if(patternCodeLockSetUpState != PatternCodeLockState::notSet) { painter.setBrush(Qt::transparent); if(patternCodeLockSetUpState == PatternCodeLockState::setted_invalid) { painter.setPen(QPen(QBrush(QColor("#FE4C40")),7,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin)); } else { painter.setPen(QPen(QBrush(QColor("#00FF80")),7,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin)); } int setListSize = setList.size(); for(int i = 0;i < setListSize;++i) { if(i < (setListSize - 1)) { painter.drawLine(smartCircularRectList.at(setList.at(i)).center(), smartCircularRectList.at(setList.at(i + 1)).center()); } } if(patternCodeLockSetUpState == PatternCodeLockState::setting) { painter.drawLine(smartCircularRectList.at(setList.last()).center(), settingMousPos); } } if(mustUpdateCircularRect) isUpdateSmartCircularRect = false; } void PatternPasswordWidget::resizeEvent(QResizeEvent *event) { isUpdateSmartCircularRect = true; QWidget::resizeEvent(event); } void PatternPasswordWidget::mouseMoveEvent(QMouseEvent *event) { auto pos = event->pos(); int currentHoverIndex = -1; if(patternCodeLockSetUpState == PatternCodeLockState::notSet) { bool mouseInSomeSmartCircular{false}; for(int i = 0;i < smartCircularRectList.size();++i) { if(smartCircularRectList.at(i).contains(pos)) { circularStateList[i] = CircularState::hoverOnInnerSamrtCircular; currentHoverIndex = i; mouseInSomeSmartCircular = true; } else { circularStateList[i] = CircularState::normal; } } if(mouseInSomeSmartCircular) { lastHoverIndex = currentHoverIndex; setCursor(Qt::PointingHandCursor); } else { setCursor(Qt::ArrowCursor); } if(!hoverTimer.isActive()) { if(this->mouseInSomeSmartCircular != mouseInSomeSmartCircular)//鼠标进入了某个小圆或从小圆出来 { this->mouseInSomeSmartCircular = mouseInSomeSmartCircular; if(this->mouseInSomeSmartCircular) { currentchangeLength = 0; } else { currentchangeLength = radiu * 0.2; } hoverTimer.start(); } } } else if(patternCodeLockSetUpState == PatternCodeLockState::setting) { bool mouseInSomeSmartCircular{false}; for(int i = 0;i < smartCircularRectList.size();++i) { if(smartCircularRectList.at(i).contains(pos)) { if(!setList.contains(i)) { setList << i; circularStateList[i] = CircularState::hoverOnInnerSamrtCircular; currentHoverIndex = i; } mouseInSomeSmartCircular = true; } } if(this->mouseInSomeSmartCircular != mouseInSomeSmartCircular) { this->mouseInSomeSmartCircular = mouseInSomeSmartCircular; if(mouseInSomeSmartCircular) { lastHoverIndex = currentHoverIndex; setCursor(Qt::PointingHandCursor); if(!hoverTimer.isActive()) { currentchangeLength = 0; hoverTimer.start(); } } else { setCursor(Qt::ArrowCursor); } } settingMousPos = pos; } update(); QWidget::mouseMoveEvent(event); } void PatternPasswordWidget::onHoverTimer() { if(patternCodeLockSetUpState == PatternCodeLockState::notSet) { if(mouseInSomeSmartCircular) { if(currentchangeLength >= (radiu * 0.2)) { hoverTimer.stop(); } currentchangeLength += 2; } else { if(currentchangeLength <= -(radiu * 0.1)) { hoverTimer.stop(); } currentchangeLength -= 2; } } else if(patternCodeLockSetUpState == PatternCodeLockState::setting) { if(currentchangeLength >= (radiu * 0.1)) { hoverTimer.stop(); } currentchangeLength += 2; } update(); } void PatternPasswordWidget::mousePressEvent(QMouseEvent *event) { if(lastHoverIndex != -1) { if(patternCodeLockSetUpState == PatternCodeLockState::notSet)//开始设置 { patternCodeLockSetUpState = PatternCodeLockState::setting; setList << lastHoverIndex; circularStateList[lastHoverIndex] = CircularState::hoverOnInnerSamrtCircular; settingMousPos = event->pos(); currentchangeLength = 0; hoverTimer.start(); update(); } } QWidget::mousePressEvent(event); } void PatternPasswordWidget::mouseReleaseEvent(QMouseEvent *event) { if(patternCodeLockSetUpState == PatternCodeLockState::setting) { patternCodeLockSetUpState = PatternCodeLockState::setted_valid; emit inputPasswordOverSignal(getPassWord()); update(); } QWidget::mouseReleaseEvent(event); } void PatternPasswordWidget::mouseDoubleClickEvent(QMouseEvent *event) { if(patternCodeLockSetUpState == PatternCodeLockState::setting && !mouseInSomeSmartCircular) { patternCodeLockSetUpState = PatternCodeLockState::setted_valid; emit inputPasswordOverSignal(getPassWord()); update(); } QWidget::mouseDoubleClickEvent(event); } QString PatternPasswordWidget::getPassWord() { QString psw; for(const int & value : setList) { psw.append(QString::number(value+1,16)); } return psw; } int PatternPasswordWidget::getNumberOfEachRowAndCol() const { return numberOfEachRowAndCol; } void PatternPasswordWidget::setNumberOfEachRowAndCol(int newNumberOfEachRowAndCol) { if(newNumberOfEachRowAndCol > 1 && newNumberOfEachRowAndCol < 10) { reset(); circularStateList.clear(); smartCircularRectList.clear(); numberOfEachRowAndCol = newNumberOfEachRowAndCol; for (int i = 0;i < numberOfEachRowAndCol;++i) { for (int j = 0;j < numberOfEachRowAndCol;++j) { circularStateList << CircularState::normal; smartCircularRectList << QRect(); } } update(); } } void PatternPasswordWidget::reset() { patternCodeLockSetUpState = PatternCodeLockState::notSet; std::fill(circularStateList.begin(),circularStateList.end(),CircularState::normal); lastHoverIndex = -1; hoverTimer.stop(); currentchangeLength = 0; isUpdateSmartCircularRect = true; mouseInSomeSmartCircular = false; setList.clear(); settingMousPos = QPoint(0,0); update(); }
三、使用方法
新建一个Dialog界面
开始布局
将widgetPassword右键->提升为->然后选择PatternPasswordWidget
类就OK!
以上就是基于Qt实现Android的图案密码效果的详细内容,更多关于Qt图案密码的资料请关注脚本之家其它相关文章!