#include "LoadingUI.h" #include #include #include #include #include #include BaseLoading::BaseLoading(QWidget *parent) : QWidget(parent), m_animationTimer(new QTimer(this)), m_animationStop(false), m_duration(1000), m_extendDuration(150) { connect(m_animationTimer,&QTimer::timeout,this, &BaseLoading::updateFrame); updateFrameRate(); } void BaseLoading::setEasingCurve(const QEasingCurve &curve) { m_curve = curve; updateFrameValues(); } void BaseLoading::setFrameRate(const int &frameRate) { m_frameRate = frameRate; updateFrameValues(); } void BaseLoading::setDuration(const int &duration) { m_duration = duration; updateFrameValues(); } void BaseLoading::setExtendDuration(const int &duration) { m_extendDuration = duration; } void BaseLoading::updateFrameData() { m_frameRects.clear(); qreal refreshTime = 1000/m_frameRate*1.0; m_animationTimer->setInterval(refreshTime); // 刷新时间s int frameCount = m_duration / refreshTime; for (int i = 0; i < frameCount; ++i) m_frameRects.append(QRect()); m_extendFrameCount = m_extendDuration / refreshTime; updateFrameRects(); } void BaseLoading::start() { m_animationTimer->start(); } void BaseLoading::stop() { m_animationStop = true; } void BaseLoading::updateFrameRate() { setFrameRate(qApp->primaryScreen()->refreshRate()); } void BaseLoading::updateFrameValues() { m_frameValues.clear(); int fCount = m_duration / refreshTime(); qreal stepValue = 1.0 / fCount; for (int i = 0; i < fCount; ++i) { qreal progress = i*stepValue; m_frameValues.append(m_curve.valueForProgress(progress)); } } ///////////////////////////////////// LoadingHorizontal::LoadingHorizontal(QWidget *parent) : BaseLoading(parent) { m_currentFrame = 0; setItemCount(1); setItemLength(10); setBackgroundColor(QColor(Qt::white)); auto curve = QEasingCurve(QEasingCurve::BezierSpline); curve.addCubicBezierSegment(QPointF(0.31f, 0.85f),QPointF(0.77f, 0.14f),QPointF(1,1)); setEasingCurve(curve); connect(this,SIGNAL(loaddingStoped()),SLOT(animationStoped())); } void LoadingHorizontal::setItemCount(const int &count) { m_itemCount = count > 0 ? count : 1; m_itemColors.clear(); for (int i = 0; i < count; ++i) { m_itemColors.append(QColor(Qt::black)); } } void LoadingHorizontal::setItemColor(const int &index, const QColor &color) { if (index < 0) { for (int i = 0; i < m_itemCount; ++i) { m_itemColors[i] = color; } } else if (index < m_itemCount){ m_itemColors[index] = color; } } void LoadingHorizontal::setItemColors(const QList &colors) { for (int i = 0; i < colors.count(); ++i) { setItemColor(i,colors.at(i)); } } void LoadingHorizontal::updateFrameRects() { int w = m_itemLength; int y = (height()-w) / 2; for (int i = 0; i < frameCount(); ++i) { int x = frameValue(i)*width(); setFrameRect(i,QRect(x,y,w,w)); } m_totalCount = frameCount()+extendFrameCount()*(m_itemCount-1); } void LoadingHorizontal::updateFrame() { m_currentFrame += 1; if (m_currentFrame >= m_totalCount) { m_currentFrame = 0; if (stopLoading()) { stopAnimationTimer(); } } update(); } void LoadingHorizontal::paintEvent(QPaintEvent *) { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true); if (!parentWidget()) { painter.fillRect(rect(),QBrush(m_bgColor)); } if (isActive()) { for (int i = 0; i < m_itemColors.count(); ++i) { QPainterPath path; auto index = m_currentFrame - extendFrameCount()*i; if (index < 0 || index >= frameCount()) continue; path.addEllipse(frameRect(index)); painter.fillPath(path,QBrush(m_itemColors.at(i))); } } } void LoadingHorizontal::resizeEvent(QResizeEvent *) { updateFrameData(); } void LoadingHorizontal::animationStoped() { m_currentFrame = 0; } ///////////////////////////////////////////////////// LoadingCircle::LoadingCircle(QWidget *parent) : LoadingHorizontal(parent) { setCurrentFrame(0); } void LoadingCircle::updateFrameRects() { auto rectRadius = itemLength() / 2; int radius = (width() < height() ? width() : height()) / 2 - rectRadius; int cx = width() / 2; int cy = height() / 2; for (int i = 0; i < frameCount(); ++i) { qreal zeta = frameValue(i) * 2 * M_PI; int x = cx - qSin(zeta) * radius; int y = cy + qCos(zeta) * radius; setFrameRect(i,QRect(x-rectRadius,y-rectRadius,itemLength(),itemLength())); } setTotalCount(frameCount()+extendFrameCount()*(itemCount()-1)); } void LoadingCircle::paintEvent(QPaintEvent *) { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true); if (!parentWidget()) { painter.fillRect(rect(),QBrush(backgroundColor())); } if (isActive()) { auto colors = itemColors(); for (int i = 0; i < colors.count(); ++i) { QPainterPath path; auto index = currentFrame() - extendFrameCount()*i; if (index < 0 || index >= frameCount()) continue; path.addEllipse(frameRect(index)); painter.fillPath(path,QBrush(colors.at(i))); } } } LoadingUI::LoadingUI(QWidget* parent) : LoadingHorizontal(parent) { Q_UNUSED(parent); this->setWindowModality(Qt::ApplicationModal); this->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::WindowStaysOnTopHint | Qt::CustomizeWindowHint); this->setAttribute(Qt::WA_TranslucentBackground, true); this->resize(800, 40); this->show(); this->setBackgroundColor(QColor(0x00, 0x00, 0x00, 0x10)); this->setItemLength(30); this->setExtendDuration(240); this->setItemCount(5); this->setDuration(2500); QList colors; colors << QColor("#99CCCC") << QColor("#FFCC99") << QColor("#FFCCCC") << QColor("#CCCCFF") << QColor("#CC9999"); this->setItemColors(colors); // w.setItemColor(-1,QColor(Qt::white)); this->updateFrameData(); this->hide(); } /// /// /// void LoadingUI::Show() { this->show(); this->start(); } /// /// /// void LoadingUI::Hide() { this->hide(); this->stop(); }