效果:
文字长度自适应,自动居中到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) #arg
class 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();
}
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);
}