#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"
5076

被折叠的 条评论
为什么被折叠?



