Qt 实现右下角消息通知队列
效果
下载地址
https://github.com/confidentFeng/QtAppProject
关键代码
NotifyWidget.cpp
// 显示下一条通知
void NotifyManager::showNext()
{
// 如果通知数目超出限制,则显示"通知当前数目界面"
if (m_notifyList.size() >= m_maxCount || m_dataQueue.isEmpty())
{
showQueueCount();
return;
}
// 创建并显示新的通知框
NotifyWidget *notifyWidget = new NotifyWidget(this); // 将管理员自身传给notifyWidget的m_manager
m_notifyList.append(notifyWidget); // 添加到通知框列表
notifyWidget->showArranged(m_notifyList.size()); // 设置新通知的显示位置
notifyWidget->setData(m_dataQueue.dequeue()); // 设置数据队列的第一个数据(dequeue,删除队列第一个元素,并返回这个元素)
showQueueCount(); // 显示队列的剩余通知数目
// 通知过了displayTime时间之后隐藏之后销毁,然后触发下面槽函数
connect(notifyWidget, &QObject::destroyed, this, [notifyWidget, this](){
// 找到被销毁的通知在队列中的索引,然后移除该通知
int index = m_notifyList.indexOf(notifyWidget);
m_notifyList.removeAt(index);
// 旧消息被移出后,就要显示通知队列中的下一个新消息,并排序
for (; index<m_notifyList.size(); index++)
m_notifyList[index]->showArranged(index+1);
// 这里是为了实现周期提示功能,一般不用到,可以注释
QTimer::singleShot(m_animateTime, this, [this](){
showNext();
});
});
}
// 显示队列的剩余通知数目
void NotifyManager::showQueueCount()
{
// 判断是否允许显示队列的剩余通知数目
if (!m_isShowQueueCount)
return;
// 数据队列大于0,说明还有未显示的剩余通知,则显示数目;否则隐藏"剩余通知数目"
if (!m_dataQueue.isEmpty())
{
m_notifyCount->showArranged(m_maxCount+1);
m_notifyCount->setCount(m_dataQueue.size());
}
else {
m_notifyCount->showArranged(0);
}
}
// 根据通知在队列中的索引,来设置其的位置,相当于更新排序
void ArrangedWidget::showArranged(int posIndex)
{
if (m_posIndex == posIndex)
return;
m_posIndex = posIndex;
// 索引小于等于0,则隐藏
if (posIndex <= 0)
{
// 如果已经隐藏,则返回
if (!isVisible())
return;
// 隐藏动画
propertyAnimationOnTarget(this, "windowOpacity", 0, m_manager->animateTime(), [this]() {
this->hide();
emit visibleChanged(false); // 隐藏信号
});
return;
}
// 计算提醒框的位置
QSize wndsize = m_manager->notifyWndSize();
QSize offset = QSize(wndsize.width(), wndsize.height()*posIndex + m_manager->spacing()*(posIndex-1));
QPoint pos = m_manager->cornerPos() - QPoint(offset.width(), offset.height());
// 如果原先是隐藏的,现在显示
if (!isVisible())
{
this->show();
this->move(pos);
this->setWindowOpacity(0);
propertyAnimationOnTarget(this, "windowOpacity", 1, m_manager->animateTime(), [this](){
emit visibleChanged(true);
});
}
else // 否则,移动位置
{
propertyAnimationOnTarget(this, "pos", pos, m_manager->animateTime());
}
}
更多代码请下载源码查看。
参考:
每日一库之 Qt5-右下角消息通知 - 知乎 (zhihu.com)