Qt实现右下角消息通知队列(滚动版本)
回到顶部 效果
上一篇博客:Qt 实现右下角消息通知队列 的通知是会定时关闭销毁的,最多同时显示 5 个通知。但有些情况下,不想前面的通知被销毁,要求保留可以一直浏览的话,就不能用了,所以改写了下,用这篇博客总结下。 点击"提示1"按钮,加入通知信息到数据队列中,并显示摇晃动画,添加到 QScrollArea 滚动区域中,方便超出 5 个通知时可以滚动浏览;可以删除,删除也添加"向右移动隐藏动画"。
下载地址
https://github.com/confidentFeng/QtAppProjec 关键代码
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); } }
点击领取Qt学习资料+视频教程~「链接」