toast带动画

#include "QtWidgetsApplication1.h"
#include <QtWidgets/QApplication>

//int main(int argc, char *argv[])
//{
//    QApplication a(argc, argv);
//    QtWidgetsApplication1 w;
//    w.show();
//    return a.exec();
//}


#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QPropertyAnimation>
#include <QTimer>
#include <QList>

#include <QDebug>

class Toast : public QWidget {
    Q_OBJECT
public:
    Toast(const QString& message, int duration, QWidget* parent = nullptr)
        : QWidget(parent), m_duration(duration) {
        setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
        setAttribute(Qt::WA_TranslucentBackground);

        m_label = new QLabel(message, this);
        m_label->setStyleSheet("background-color: rgba(0, 0, 0, 0.7); color: white; padding: 10px; border-radius: 5px;");
        m_label->adjustSize();

        //m_timer = new QTimer(this);
        //connect(m_timer, &QTimer::timeout, this, &Toast::hideWithAnimation);
        //m_timer->setSingleShot(true);

        m_countdownTimer = new QTimer(this);
        connect(m_countdownTimer, &QTimer::timeout, this, &Toast::countdownFinished);
        m_countdownTimer->setSingleShot(true);
    }

    void showWithAnimation(const QPoint& pos) {
        move(pos);
        show();
        //m_timer->start(m_duration);
        m_countdownTimer->start(3000); // 启动200毫秒倒计时
    }

signals:
    void toastHidden(int height); // 发送信号以通知 ToastManager 更新位置

private slots:
    void countdownFinished() {
        hideWithAnimation(); // 倒计时结束后调用隐藏动画

        qInfo() << "hideWithAnimation";

        m_isTimeout = true;

            emit toastHidden(height()); // 通知 ToastManager,传递高度
    }

    void hideWithAnimation() {
        //QPropertyAnimation* animation = new QPropertyAnimation(this, "pos");
        //animation->setDuration(300);
        //animation->setStartValue(pos());
        //animation->setEndValue(QPoint(x(), y() - 50)); // 向上移动
        //animation->setEasingCurve(QEasingCurve::OutCubic);

        //connect(animation, &QPropertyAnimation::finished, [this]() {
        //    emit toastHidden(height()); // 通知 ToastManager,传递高度
        //    deleteLater(); // 销毁对象

        //    qInfo() << "deleteLater";
        //    });
        //animation->start();
    }

public:
    bool m_isTimeout{false};

private:
    QLabel* m_label;
    //QTimer* m_timer;
    QTimer* m_countdownTimer;
    int m_duration;
};


class ToastManager : public QWidget {
    Q_OBJECT
public:
    ToastManager() {
        QVBoxLayout* layout = new QVBoxLayout(this);
        QPushButton* button = new QPushButton("Start Toasts", this);
        layout->addWidget(button);
        setLayout(layout);

        //m_timer = new QTimer(this);
        //connect(m_timer, &QTimer::timeout, this, &ToastManager::showToast);
        //m_timer->setInterval(1000); // 每100ms弹出一个Toast

        connect(button, &QPushButton::clicked, this, &ToastManager::startToasts);
    }

private slots:
    void startToasts() {
        //m_timer->start(); // 启动定时器
        showToast();
    }

    void showToast() {
        Toast* toast = new Toast("This is a toast message!", 3000, this);
        connect(toast, &Toast::toastHidden, this, &ToastManager::adjustToasts);
        int toastCount = m_toastList.size();
        toast->showWithAnimation(QPoint(10, 10 + toastCount * 60));

        m_toastList.push_back(toast);
    }

    void adjustToasts(int height) {
        // 更新所有后续 Toast 的位置


        int i = 0;

        for (auto it = m_toastList.begin(); it != m_toastList.end(); ) {
            int newY = 10 + i * 60; // 重新计算新位置
            if (!(*it)->m_isTimeout)
            {

            // 动画移动每个 Toast
                QPropertyAnimation* animation = new QPropertyAnimation(*it, "pos");
                //animation->setParent(*it);
                animation->setDuration(300);
                animation->setStartValue((*it)->pos());
                animation->setEndValue(QPoint(10, newY));
                animation->setEasingCurve(QEasingCurve::OutCubic);
                animation->start();

                i++;
                ++it; // 继续下一个元素
            }
            else {
#if 0
                m_list.push_back(*it);
                QPropertyAnimation* animation = new QPropertyAnimation(*it, "pos");
                //animation->setParent(*it);
                animation->setDuration(300);
                animation->setStartValue((*it)->pos());
                animation->setEndValue(QPoint(10, newY));
                animation->setEasingCurve(QEasingCurve::OutCubic);
                animation->start();
                connect(animation, &QPropertyAnimation::finished, [this]() {

                     //auto o = sender();
                     //if (o)
                     //{
                        // o->parent()->deleteLater();
                        // qInfo() << "deleteLater";
                     //}

                    QWidget* o = m_list.front();
                    if (o)
                    {
                        o->deleteLater();
                    }

                    m_list.pop_front(); // 移除第一个元素


                    });
                animation->start();

                it = m_toastList.erase(it); // 移除元素并返回下一个迭代器


#endif

                it = m_toastList.erase(it); // 移除元素并返回下一个迭代器
                (*it)->deleteLater();
            }

        }
    }

private:
    //QTimer* m_timer;
    std::list <Toast*>m_toastList;
    std::list <Toast*>m_list;
};

int main(int argc, char* argv[]) {
    QApplication app(argc, argv);

    ToastManager manager;
    manager.setFixedSize(300, 400);
    manager.show();

    return app.exec();
}

#include "main.moc"
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值