效果:
文字长度自适应,自动居中到parent,会透明渐变消失。
CustomToast::MessageToast(QS("最多添加50张图片"),this);
1. CustomToast.h
#pragma once#include <QFrame>class CustomToast : public QFrame {Q_OBJECT
public:static void MessageToast(const QString &text, QWidget *parent = nullptr, int timeout = 1500);private:CustomToast(QWidget *parent = nullptr, int timeout = 1500);void setText(const QString &text);
private:class Impl;std::shared_ptr<Impl> m_impl = nullptr;class Ui;std::shared_ptr<Ui> ui = nullptr;
};
2. CustomToast.cpp
#include "CustomToast.h"#include <QGraphicsOpacityEffect>
#include <QHBoxLayout>
#include <QLabel>
#include <QPropertyAnimation>
#include <QTimer>#define STR(arg) #argclass CustomToast::Ui {public:void setupUi(QWidget *parent){layout = new QHBoxLayout(parent);parent->setLayout(layout);parent->setContentsMargins(0, 0, 0, 0);layout->setContentsMargins(0, 0, 0, 0);layout->setContentsMargins(16, 8, 16, 8);labelIcon = new QLabel(parent);labelText = new QLabel(parent);auto iconLayout = new QHBoxLayout(parent);iconLayout->addWidget(labelIcon);iconLayout->setContentsMargins(0, 2, 0, 2);layout->addLayout(iconLayout);layout->addWidget(labelText);layout->setSpacing(3);labelIcon->setFixedSize(16, 16);labelText->setMinimumHeight(20);labelText->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);parent->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);parent->setObjectName(STR(CustomToast));labelIcon->setObjectName(STR(labelIcon));labelText->setObjectName(STR(labelText));}QHBoxLayout *layout = nullptr;QLabel *labelIcon = nullptr;QLabel *labelText = nullptr;
};class CustomToast::Impl {
public:Impl(CustomToast *parent, int timeout) : m_parent(parent), m_timeout(timeout){}void startOpacityAnimation(){auto graphicsOpacityEffect = new QGraphicsOpacityEffect(m_parent);graphicsOpacityEffect->setOpacity(1.0);m_parent->setGraphicsEffect(graphicsOpacityEffect);auto opacityAnimation = new QPropertyAnimation(graphicsOpacityEffect, "opacity");opacityAnimation->setDuration(m_timeout);opacityAnimation->setStartValue(1.0);opacityAnimation->setEndValue(0);opacityAnimation->setEasingCurve(QEasingCurve::InCubic);opacityAnimation->start();}void centerToParent(){auto grandParent = m_parent->parentWidget();if (grandParent) {m_parent->move(grandParent->width() / 2 - m_parent->width() / 2, grandParent->height() / 2 - m_parent->height() / 2);}}void deleteLater(){QTimer::singleShot(m_timeout, m_parent, [=] { m_parent->deleteLater(); });}private:QWidget *m_parent = nullptr;int m_timeout = 1500;
};void
CustomToast::MessageToast(const QString &text, QWidget *parent /*= nullptr*/, int timeout /*= 1500*/)
{auto toast = new CustomToast(parent, timeout);toast->setText(text);toast->show();m_impl->centerToParent();
}CustomToast::CustomToast(QWidget *parent, int timeout) :QFrame(parent), ui(std::make_shared<Ui>()), m_impl(std::make_shared<Impl>(this, timeout))
{ui->setupUi(this);m_impl->centerToParent();m_impl->startOpacityAnimation();m_impl->deleteLater();
}void
CustomToast::setText(const QString &text)
{ui->labelText->setText(text);adjustSize();
}
3. 样式表:
CustomToast{background: rgba(0, 0, 0, 0.8);border-radius: 4px;
}
CustomToast #labelText{color: #FFFFFF;font-family: Microsoft YaHei;font-size: 14px;font-weight: 400;
}
CustomToast #labelIcon{border-image: url(:/img/toast/info.png);
}