Qt 实现右下角消息通知队列(滚动版本)
效果
上一篇博客:Qt 实现右下角消息通知队列 的通知是会定时关闭销毁的,最多同时显示 5 个通知。但有些情况下,不想前面的通知被销毁,要求保留可以一直浏览的话,就不能用了,所以改写了下,用这篇博客总结下。
- 点击"提示1“按钮,加入通知信息到数据队列中,并显示摇晃动画,添加到
QScrollArea
滚动区域中,方便超出 5 个通知时可以滚动浏览; - 可以删除,删除也添加"向右移动隐藏动画"。
下载地址
https://github.com/confidentFeng/QtAppProject
关键代码
NotifyWidget.cpp
NotifyManager::NotifyManager(QWidget *parent) : QWidget(parent)
{
this->setFixedSize(320, 600);
this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
this->setObjectName("NotifyManager");
// 创建一个子窗口,这个子窗口交给滚动区域
QWidget* pSubWidget = new QWidget(this);
// 创建滚动区域
m_pScrollArea = new QScrollArea(this);
m_pScrollArea->setFixedSize(width(), NOTIFY_HEIGHT);
m_pScrollArea->setWidgetResizable(true); // 决定着滚动区域是否应调整子widget的大小
m_pScrollArea->verticalScrollBar()->setSingleStep(NOTIFY_HEIGHT/3); // 设置步长,每次滚动滚轮只上移或下移一个item
m_pScrollArea->setWidget(pSubWidget); // 子widget可以使用QScrollArea::setWidget(QWidget *widget)来指定
m_pScrollArea->move(QPoint(0, height() - NOTIFY_HEIGHT));
// 给子窗口设置一个垂直布局,方便动态添加通知
m_pLayoutSub = new QVBoxLayout(pSubWidget);
m_pLayoutSub->setSpacing(NOTIFY_SPACE);
m_pLayoutSub->setContentsMargins(0,0,0,0);
m_pLayoutSub->addStretch();
// 初始化队列的通知数目界面
m_pNotifyCntWidget = new NotifyCountWidget(this);
m_pNotifyCntWidget->hide();
// 显示队列的通知数目的定时器
m_pTimerCnt = new QTimer(this);
m_pTimerCnt->setSingleShot(true);
m_pTimerCnt->setInterval(3000);
connect(m_pTimerCnt, &QTimer::timeout, [=]{
m_pNotifyCntWidget->hide();
m_pNotifyCntWidget->isStartAnim(false); // 结束动画
});
// 队列定时器
m_pTimerQueue = new QTimer(this);
m_pTimerQueue->setInterval(500);
m_pTimerQueue->start();
connect(m_pTimerQueue, &QTimer::timeout, [=]{
showQueueNotify();
});
}
// 通知入队
void NotifyManager::notifyEnqueue(const QString &title, const QString &body, const QVariantMap &data)
{
// 将标题栏和内容数据添加到队列中
QVariantMap tmp = data;
tmp.insert("title", title);
tmp.insert("body", body);
tmp.insert("icon", m_defaultIcon);
m_dataQueue.enqueue(tmp);
}
// 显示队列中的通知
void NotifyManager::showQueueNotify()
{
m_pTimerQueue->stop();
// 如果通知数目超出限制,则显示"通知当前数目界面"
if (m_notifyCount >= NOTIFY_MAX_COUNT || m_dataQueue.isEmpty()) {
m_pTimerQueue->start();
return;
}
// 创建并显示新的通知
NotifyWidget *notifyWidget = new NotifyWidget(this); // 将管理员自身传给notifyWidget的m_manager
notifyWidget->setData(m_dataQueue.dequeue()); // 设置数据队列的第一个数据(dequeue,删除队列第一个元素,并返回这个元素)
m_pLayoutSub->insertWidget(0, notifyWidget);
m_notifyCount++;
// 显示新的通知时,摇晃动画
animationShake(notifyWidget, 800, [=](){
m_pTimerQueue->start();
});
// 通知销毁之后触发下面槽函数
connect(notifyWidget, &QObject::destroyed, this, [this](){
m_notifyCount--;
// 更新滚动区域的高度
updateAreaHeight();
});
// 更新滚动区域的高度
updateAreaHeight();
}
// 更新滚动区域的高度
void NotifyManager::updateAreaHeight()
{
// 布局最前面插入通知
if(m_notifyCount < VIEW_ITEM) {
m_pScrollArea->move(QPoint(0, height() - NOTIFY_HEIGHT*m_notifyCount));
m_pScrollArea->setFixedHeight(NOTIFY_HEIGHT*m_notifyCount);
}
else {
// 显示队列的通知数目
showQueueCount();
m_pScrollArea->setFixedHeight(NOTIFY_HEIGHT*(VIEW_ITEM-1) -10);
}
}
更多代码请下载源码查看。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
2019-12-16 环境变量对于 VS 有什么用?
2019-12-16 解决 Github 图片加载慢的问题
2018-12-16 [Qt及Qt Quick开发实战精解] 第1章 多文档编辑器
2018-12-16 Qt应用程序主窗口之一:主窗口框架