#include "ArrangedWidget.h" // 动画 static QPropertyAnimation *propertyAnimationOnTarget( QObject *target, const QByteArray &propertyName, const QVariant &endValue, int duration) { QPropertyAnimation *animation = new QPropertyAnimation(target, propertyName, target); animation->setStartValue(target->property(propertyName)); animation->setEndValue(endValue); animation->setDuration(duration); animation->start(QAbstractAnimation::DeleteWhenStopped); return animation; } // 动画模板 template static inline void propertyAnimationOnTarget(QObject *target, const QByteArray &propertyName, const QVariant &endValue, int duration, func onFinished) { QPropertyAnimation *animation = propertyAnimationOnTarget(target, propertyName, endValue, duration); QObject::connect(animation, &QPropertyAnimation::finished, target, onFinished); } ArrangedWidget::ArrangedWidget(NotifyManager *manager, QWidget *parent) : QWidget(parent) { // 初始化界面 this->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::WindowStaysOnTopHint); // 必须设置为Qt::Tools this->setAttribute(Qt::WA_NoSystemBackground, true); this->setAttribute(Qt::WA_TranslucentBackground, true); this->setFixedSize(manager->notifyWndSize()); // 初始化成员变量 m_manager = manager; // NotifyWidget创建的时候传入 m_posIndex = 0; // manager销毁,界面也跟着销毁 connect(manager, &QObject::destroyed, this, &QObject::deleteLater); } // 根据通知在队列中的索引,来设置其的位置,相当于更新排序 void ArrangedWidget::showArranged(int posIndex) { if (m_posIndex == posIndex) return; m_posIndex = posIndex; // 索引小于等于0,则隐藏 if (posIndex <= 0) { // 如果已经隐藏,则返回 if (!isVisible()) return; // 隐藏动画 propertyAnimationOnTarget(this, "windowOpacity", 0, m_manager->animateTime(), [this]() { this->hide(); emit visibleChanged(false); // 隐藏信号 }); return; } // 计算提醒框的位置 QSize wndsize = m_manager->notifyWndSize(); QSize offset = QSize(wndsize.width(), wndsize.height() * posIndex + m_manager->spacing() * (posIndex - 1)); QPoint pos = m_manager->cornerPos() - QPoint(offset.width() / 2, -offset.height()); // 如果原先是隐藏的,现在显示 if (!isVisible()) { this->show(); this->move(pos); this->setWindowOpacity(0); propertyAnimationOnTarget(this, "windowOpacity", 1, m_manager->animateTime(), [this]() { emit visibleChanged(true); }); } else // 否则,移动位置 { propertyAnimationOnTarget(this, "pos", pos, m_manager->animateTime()); } }